# ProcessOne > Scalable, powerful and versatile multiprotocol messaging platforms Public Ghost content for AI and LLM tooling. This file includes a bounded export of public pages first, then recent public posts. Append `.md` to any post or page URL to get the content in Markdown (for example, `/example-post.md`). ## Pages ### Pioneering the Future of Messaging URL: https://www.process-one.net/company/ Last updated: 2025-09-22T14:59:01.000Z ## What is ProcessOne? ProcessOne is the enterprise messaging infrastructure company behind ejabberd, the battle-tested platform that powered WhatsApp's growth to billions of users. We provide scalable, multi-protocol messaging solutions for businesses needing reliable real-time communication at any scale. **Founded:** 1999 **Specialty:** Messaging at scale (1M to 1B+ users) **Deployment:** On-premise & Cloud ![](https://www.process-one.net/content/images/2024/10/elisabeth-daveine-Afrique-du-Sud-1270.webp) ## We love scale... ... very large scale It’s true—our code powers the **WhatsApp** messaging platform, enabling conversations between over a **billion** users worldwide. We specialize in **large-scale**, **critical**, and highly **custom** projects, leveraging ejabberd as the core building block for tailored solutions. For companies looking to scale without the complexity of managing real-time services, our [fluux](https://fluux.io/?ref=process-one.net) platform offers a standard, off-the-shelf managed ejabberd solution designed to make scaling effortless. ## When to Choose ProcessOne ✓ **Scale Requirements**: You need to handle 1M+ concurrent connections ✓ **Data Sovereignty**: You require on-premise deployment for compliance ✓ **Cost Predictability**: You want fixed infrastructure costs, not per-message or per-user pricing ✓ **Protocol Flexibility**: You need XMPP, Matrix, MQTT, and SIP in one platform ✓ **Proven Reliability**: You can't afford downtime (99.999% uptime SLA) ## Build on Open Messaging Standards with our Open Source code We believe in building on **open standards**, giving you full control over your stack and the ability to own your data. Our **open-source** platform, [ejabberd](https://github.com/processone/ejabberd?ref=process-one.net), supports a wide range of protocols, offering you flexibility and transparency in your messaging solutions: - [XMPP (eXtensible Messaging and Presence Protocol)](https://xmpp.org/?ref=process-one.net): Perfect for enterprise chat, presence, and real-time collaboration. - [MQTT (Message Queuing Telemetry Transport)](https://mqtt.org/?ref=process-one.net): Ideal for IoT device communication and telemetry at scale. - [Session Initiation Protocol (SIP)](https://en.wikipedia.org/wiki/Session%5FInitiation%5FProtocol?ref=process-one.net): Voice and video calling integration for unified communications. - [Matrix](https://matrix.org/?ref=process-one.net): Federated messaging for decentralized architectures. - STUN/TURN: Essential tools that enable seamless voice and video connections between parties. ## Proven Track Record - **2 Billion+** users served across all deployments - **2 Million** concurrent connections on a single node - **99.999%** uptime SLA for large enterprise customers - **25+ years** of messaging expertise since 1999, served by a [team of messaging veterans](https://www.process-one.net/team/) - **Top deployments**: WhatsApp, Riot Games, BBC, Nintendo, Orange, ... --- ![](https://www.process-one.net/content/images/2024/10/snaptosnack-V_os6YhXLnk-unsplash.webp) ## Contact **Headquarters** 4, rue Pétrelle 75009 Paris France ✉️ [contact@process-one.net](mailto:contact@process-one.net) [Contact](https://www.process-one.net/contact) ### Hardened Messaging URL: https://www.process-one.net/hardened-messaging/ Last updated: 2024-10-24T15:03:32.000Z **We design systems for high-availability, security, and resilience using Erlang, state-of-the-art encryption, and expert programming craft.** > ejabberd, like all our back-end software, inherits those unique capabilities: high-availability, security, and resilience. ## Our Secret Weapon: Erlang At ProcessOne, our approach to building hardened messaging systems starts with Erlang—a not-so-secret weapon in our technology arsenal. Erlang is an open-source virtual machine designed specifically for creating resilient, highly scalable messaging platforms, like our very own ejabberd. ## Why Erlang Powers Our Scalability From a user’s perspective, scalability is key for a seamless experience, especially in large-scale messaging applications. Erlang, originally designed for real-time communication, provides a unique advantage: its architecture enables it to handle millions of concurrent connections on a single server. Our ejabberd platform is the best showcase of Erlang’s capabilities, consistently proving to be the most reliable and scalable messaging server available today. ## Built for Scale: Optimizing CPU Utilization Erlang uses a lightweight process architecture, supported by a one-of-a-kind scheduler that optimizes CPU resources. This design enables efficient multicore usage, essential for powering large-scale messaging services. Under heavy load, Erlang can maximize CPU usage across all cores, ensuring that every server in your cluster performs at its best. This becomes even more critical as cluster size increases and inter-node synchronization grows more complex. ![](https://www.process-one.net/content/images/2024/10/top-100_-all-cores.png) Using all your CPU cores ## Designed for Low-Latency Originally designed for telecom infrastructure, Erlang operates as a soft real-time platform, ensuring response times under 20ms. In the messaging world, where even minor delays can lead to significant backlogs, this low-latency capability is invaluable. A short lag can create cascading effects, causing message queues to grow exponentially and recovery times to extend for hours—or even days. ## Resilient by Design: Handling Failure with Grace Erlang was built with failure in mind. It offers robust mechanisms for graceful recovery, including hot code reloading. This capability allows us to update live systems without downtime, ensuring seamless service for users. But why is hot code reloading important for messaging systems? The greatest stress on a messaging system happens during restarts. At this critical moment, all connections attempt to re-establish simultaneously, leading to an overwhelming surge of new requests. This is often the time when lesser systems collapse under pressure. Our servers are designed for cold starts, making them more resilient to sudden traffic spikes and denial of service attacks. By preparing for this “worst-case scenario,” we avoid a situation where restarting the service could lead to self-imposed Distributed Denial of Service (DDoS) conditions. ## State-of-the-Art Security and Encryption ProcessOne’s platform supports the latest in messaging security, including modern TLS protocols and the ability to block weak and obsolete encryption methods. Our system complies with strict security standards, such as those required by AMEX, and can enable end-to-end encryption for even greater privacy. Our corporate offering even supports FIPS security requirements. ## Secure by Nature: Built on Erlang’s Virtual Machine Erlang’s virtual machine offers inherent security benefits by limiting attack vectors. For example, buffer overflows are impossible in Erlang, making it more secure by design. Furthermore, our team of experienced engineers builds systems with a focus on massive scale and security from the ground up. ## The Result: Hardened Messaging All these features—scalability, low-latency performance, failure tolerance, and robust security—come together in what we call “Hardened Messaging.” Our approach to building messaging systems meets the demanding 99.999% uptime requirements (or more), providing a level of reliability that’s nearly mythical in the industry. ### Messaging Use Cases URL: https://www.process-one.net/use-cases/ Last updated: 2024-10-11T13:41:30.000Z > At ProcessOne, we understand that **messaging** is the **backbone** of a wide range of applications. From real-time interactions to machine communications, our high-scale, highly available platform adapts to meet the demands of various industries. Below are some of the key use cases our platform supports: ## Social networks ### Private messaging is at the heart of every social platform If you are building a social network in any form, a private messaging infrastructure is essential. There’s no way around it, and it’s even better if you make it a core part of your service. Social networks have been the dominant force for more than a decade, with feeds being the most prominent feature for a long time. However, this is no longer the case. On all major social networks—Facebook, Instagram, Snapchat, and others—the primary reason users keep coming back to the app and maintaining connections is the private space: conversations, whether through group chats or one-on-one messaging. *Our software stack, built around *ejabberd*, is the most reliable and scalable tool to build a chat feature for your user base. After all, it’s the foundation that made *WhatsApp* possible.* As Mark Zuckerberg said in 2023, Whatsapp would be the target to build the private social network of the future, if they were starting from scratch. > “If you’re envisioning what will be the private social platform of the future, starting from scratch, I think it would basically look like WhatsApp,” > \-- Mark Zuckerberg ### *Sources* - *In English:* [*Mark Zuckerberg Taps the Strengths of WhatsApp*](https://www.nytimes.com/2023/11/08/technology/mark-zuckerberg-whatsapp.html?ref=process-one.net) *(New York Times)* - *In French:* [*Pour les réseaux sociaux, la fin d’un règne ?*](https://www.lemonde.fr/pixels/article/2024/10/06/pour-les-reseaux-sociaux-la-fin-d-un-regne%5F6344843%5F4408996.html?ref=process-one.net) *(For social networks, the end of an era?, Le Monde)* ## Gaming Gaming is inherently social. We play to connect with friends and meet new ones. Whether strategizing with teammates or discussing game tactics, messaging plays a crucial role in enhancing the experience. Push notifications also help players re-engage by inviting friends into games when boredom strikes. In some cases, game events can be routed through the same messaging platform, simplifying infrastructure management and reducing operational complexity. Leading gaming companies trust ejabberd to power their chat services, push and event mechanisms, including **Nintendo** (for Switch console push and messaging services), **CCP** (Eve Online), **Riot Games** (League of Legends), **Ubisoft**, **Winamax**, and **Electronic Arts**. ## Corporate messaging When we think of messaging, corporate communication often comes to mind. Messaging tools have become integral to collaboration across enterprises and government organizations. ProcessOne’s platform is widely used in such environments because it empowers organizations to fully own and customize their messaging solutions. Companies can retain control over both their data and software stack, seamlessly integrate the messaging service with internal workflows, and define their own policies for monitoring and archiving. Our messaging platform is used to power all type of corporate chat service: - **Employee-to-employee:** A vital tool for internal collaboration. - **Employee-to-partners**: Through federation, businesses can communicate externally while ensuring that sensitive internal messages remain within their own network. - **Employee-to-customers**: Our platform not only supports standard customer service workflows but also enables businesses to implement highly specific, customized workflows that can blend human agents with app-driven interactions. When integrated with internal messaging, this setup boosts productivity by allowing teams to use a single tool for both internal and external communication. - **Employee-to-core business applications**: With the rise of AI and conversational interfaces, organizations are increasingly integrating chatbots into workflows, blending human interaction with business applications. In terms of feature scope, our platform goes beyond simple text and group chat, offering capabilities such as rich presence, real-time collaboration, shared drawing boards, file attachments, and even voice and video chat. Our solution is trusted in sectors where **quality of service** and **security** are paramount, including **Banking** and **Finance**, as well as **Healthcare**. ## Internet of Things When building and controlling a network of devices, the best approach is to connect them to a central cluster running our platform. Due to firewalls protecting many IoT devices, connecting directly to them is often impractical. Our platform enables seamless communication by using the appropriate protocol for each task, depending on the traffic demands—whether you need to collect vast amounts of data from sensors or dispatch control messages to specific devices. Once connected, data flows bidirectionally, allowing full control and monitoring. Major device manufacturers rely on our platform to manage hundreds of millions of devices, including companies like **Nintendo**, **Linksys**, **AVG/Avast**, and **YouView**. Our platform is even trusted in high-security contexts, such as controlling alarm system networks where **reliability** and **security** are critical. ### Advanced Messaging Infrastructure & Services URL: https://www.process-one.net/advanced-messaging/ Last updated: 2024-10-21T12:31:09.000Z ![](https://www.process-one.net/content/images/2024/10/fabian-jones-k1QtoTUVD1E-unsplash.webp) ## ejabberd Leading messaging server for [XMPP](https://www.process-one.net/xmpp/), MQTT, Matrix and SIP [See why billions of users rely on ejabberd](https://www.process-one.net/ejabberd/) ejabberd is a robust messaging platform developed by ProcessOne since 2002, designed to support billions of users worldwide. It stands at the core of our server-software stack, bringing unmatched reliability and scalability to your messaging infrastructure. ![](https://www.process-one.net/content/images/2024/10/eric-prouzet-_MOOIjWPzSM-unsplash.webp) ## fluux Managed ejabberd to scale your service without limits or troubles [Experience seamless scaling with fluux](https://fluux.io/?ref=process-one.net) Scaling a real-time messaging service is complex; every architectural mistake or poor design decision can threaten your service at the worst moment—when your application goes viral or is needed most. fluux offers a standards-based, managed ejabberd solution designed to scale effortlessly, allowing you to focus on your application development without the headaches of infrastructure management. ![](https://www.process-one.net/content/images/2024/10/tom-chrostek-JT4GGgI2H98-unsplash.webp) ## Services Supporting you for the long term [Contact us](https://www.process-one.net/contact/) Our mission is to help you build the most reliable messaging service, one you can count on in all circumstances. We don’t just provide a great software stack; we ensure your success with a range of services dedicated to designing reliable and scalable messaging solutions: - **Consulting**: Expert guidance to optimize your messaging architecture. - **Custom Development**: Tailored solutions to meet your unique requirements. - **Large-Scale Benchmark & Tuning**: Performance testing to ensure scalability. Get in touch with our team to explore how we can support your messaging needs! ### What is XMPP? URL: https://www.process-one.net/xmpp/ Last updated: 2024-09-24T15:17:12.000Z ![](https://www.process-one.net/content/images/2024/09/1200px-XMPP_logo.svg-1.png) The eXtensible Messaging and Presence Protocol, aka XMPP, is a **standard** actively developed since 1999\. It is promoted by a [vibrant community](https://xmpp.org/?ref=process-one.net) and supported by the industry. ## The most flexible messaging protocol Why is it still today the golden standard to develop messaging applications? XMPP is based on XML, an HTML descendant and thus adopts the familiar semantic markup that powers the web since 1989. **Why does it matter ?** Because it support attributes, nested elements, and namespaces, making it formally defined and still totally extensible, even to support third-party or custom [use cases](https://www.process-one.net/use-cases/). > XMPP is totally extensible and adapts to new use cases XMPP in itself is defined by a core, composed of two RFC approved as the standard by the Internet Engineering Task Force, the body that defines Internet protocols. This part changes very rarely. On top of that basis, the community, driven by the XMPP Standard Foundation has been able to defined hundreds of extensions, formally defined through their XML schema that adds features to the protocol. And they are not alone. Many companies leverage the flexibility of XMPP to extend the protocol for their own custom use. It allows them to implement custom business-oriented features in their client, or invent totally new use cases, for example their own control protocol for headless connected devices. ## An open standard with a large code offering = Freedom With XMPP, you are not stuck with a single vendor. Being an open standard, XMPP deployments are enabled by a massive offering of servers, clients and libraries. And guess what ? They are all compliants, works together and can be replaced as you see fit. > With XMPP > > Your messaging future is in your hands. > > You own the data, but you also own the choice of tools and partners. ## A protocol that speak both to machines and humans XML is readable. It means that you can understand what the client is doing by dumping the XML conversation with the server. You are not limited by what the XMPP library you are using implements to build your client. You can send XMPP stanza at a low level, a simple XML and very readable structure that can leverage any supported server or client feature. Here is is a message: TODO and here is an IQ stanza, with the server response: TODO Even if you have never played with the XMPP protocol, you can probably guess what is happening there (A message being send to another user and a request to retrieve the contact list of a user from the server). You have questions on which tools, servers, library to use to implement your messaging service ? You are in the right place. Get in touch ! ### Specification & Reference Sheets URL: https://www.process-one.net/ejabberd-features/ Last updated: 2026-01-22T16:30:26.000Z ejabberd offers one of the most comprehensive feature sets among instant messaging servers. Built on the robust foundation of the eXtensible Messaging and Presence Protocol (XMPP), it integrates a vast range of XMPP Extension Protocols (XEPs) to support diverse use cases. Additionally, the ejabberd Business Edition (eBE) extends functionality with high-level features tailored for enterprise needs. This page provides an overview of the supported protocols, extensions, and features, and emphasizes those that are exclusive to ejabberd Business Edition. To help you select the right ejabberd version for your needs, it highlights the key differences between the standard open-source edition and ejabberd Business Edition. ## Core XMPP Specifications | RFC | Title | Description | Community Server (eCS) | Business Edition (eBE) | | -------- | ------------------------------------ | ----------------------------------------- | ---------------------- | ---------------------- | | RFC-3920 | XMPP: Core | XMPP Core mechanisms and routing | ✔ | ✔ | | RFC-3921 | XMPP: Instant Messaging and Presence | XMPP IM and presence | ✔ | ✔ | | RFC-6120 | XMPP: Core | XMPP Core mechanisms and routing (update) | ✔ | ✔ | | RFC-6121 | XMPP: Instant Messaging and Presence | XMPP IM and presence (update) | ✔ | ✔ | | RFC-6122 | XMPP: Address Format | Format for user and services addresses | ✔ | ✔ | ## Common XMPP Extensions | RFC | Title | Description | Community Server (eCS) | Business Edition (eBE) | | ------------------------------------------------------------------------ | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ---------------------- | | [XEP-0004](http://xmpp.org/extensions/xep-0004.html?ref=process-one.net) | Data Forms | Queries and responses between entities, with forms | ✔ | ✔ | | [XEP-0012](http://xmpp.org/extensions/xep-0012.html?ref=process-one.net) | Last Activity | Date of the last activity of an entity before going offline | ✔ | ✔ | | [XEP-0013](http://xmpp.org/extensions/xep-0013.html?ref=process-one.net) | Flexible Offline Message Retrieval | Filter offline messages, to prevent storm when reconnecting | ✔ | ✔ | | [XEP-0016](http://xmpp.org/extensions/xep-0016.html?ref=process-one.net) | Privacy Lists | Personal rules to prevent spam and abuse, and protect privacy (for example invisibility) | ✔ | ✔ | | [XEP-0022](http://xmpp.org/extensions/xep-0022.html?ref=process-one.net) | Message Events | Request and respond to events relating to the delivery, display, and composition of messages | ✔ | ✔ | | [XEP-0023](http://xmpp.org/extensions/xep-0023.html?ref=process-one.net) | Message Expiration | Expiry time of offline message | ✔ | ✔ | | [XEP-0030](http://xmpp.org/extensions/xep-0030.html?ref=process-one.net) | Service Discovery | To query entity's features and capabilities | ✔ | ✔ | | [XEP-0033](http://xmpp.org/extensions/xep-0033.html?ref=process-one.net) | Extended Stanza Addressing | To send messages to multiple recepients, like email's to:, cc: and bcc: lists | ✔ | ✔ | | [XEP-0039](http://xmpp.org/extensions/xep-0039.html?ref=process-one.net) | Statistics Gathering | To query statistics of services | ✔ | ✔ | | [XEP-0045](http://xmpp.org/extensions/xep-0045.html?ref=process-one.net) | Multi-User Chat | For conferences with multiple users, with a large number of features (privacy, security, invitations, etc.) | ✔ | ✔ | | [XEP-0048](http://xmpp.org/extensions/xep-0048.html?ref=process-one.net) | Bookmarks | Store bookmarks to MUC rooms and web pages | ✔ | ✔ | | [XEP-0049](http://xmpp.org/extensions/xep-0049.html?ref=process-one.net) | Private XML Storage | For server-side storage of simple XML like config options | ✔ | ✔ | | [XEP-0050](http://xmpp.org/extensions/xep-0050.html?ref=process-one.net) | Ad-Hoc Commands | Sequences of forms (like wizards) for automated data exchange (human to machine, machine to machine) | ✔ | ✔ | | [XEP-0054](http://xmpp.org/extensions/xep-0054.html?ref=process-one.net) | vcard-temp | For vCards (business cards) storage and queries | ✔ | ✔ | | [XEP-0055](http://xmpp.org/extensions/xep-0055.html?ref=process-one.net) | Jabber Search | Forms dedicated to search | ✔ | ✔ | | [XEP-0059](http://xmpp.org/extensions/xep-0059.html?ref=process-one.net) | Result Set Management | Paging of large results sets | ✔ | ✔ | | [XEP-0060](http://xmpp.org/extensions/xep-0060.html?ref=process-one.net) | Publish-Subscribe | Publish and subscribe pattern applied to XMPP | ✔ | ✔ | | [XEP-0065](http://xmpp.org/extensions/xep-0065.html?ref=process-one.net) | SOCKS5 Bytestreams | Relay for file transfers | ✔ | ✔ | | [XEP-0077](http://xmpp.org/extensions/xep-0077.html?ref=process-one.net) | In-band Registration | For account creations, from the XMPP client | ✔ | ✔ | | [XEP-0078](http://xmpp.org/extensions/xep-0078.html?ref=process-one.net) | Non-SASL Authentication | Authentication method | ✔ | ✔ | | [XEP-0082](http://xmpp.org/extensions/xep-0082.html?ref=process-one.net) | XMPP Date and Time Profiles | Standard 08601 for dates | ✔ | ✔ | | [XEP-0085](http://xmpp.org/extensions/xep-0085.html?ref=process-one.net) | Chat State Notifications | Typing indicator | ✔ | ✔ | | [XEP-0086](http://xmpp.org/extensions/xep-0086.html?ref=process-one.net) | Error Condition Mappings | Error codes definition | ✔ | ✔ | | [XEP-0092](http://xmpp.org/extensions/xep-0092.html?ref=process-one.net) | Software Version | Discovery of software release numbers | ✔ | ✔ | | [XEP-0100](http://xmpp.org/extensions/xep-0100.html?ref=process-one.net) | Gateway Interaction | Interoperability with private communities : Microsoft MSN/WLM, Yahoo! Messenger, ICQ, AOL IM, IRC, Twitter | ✔ | ✔ | | [XEP-0106](http://xmpp.org/extensions/xep-0106.html?ref=process-one.net) | JID Escaping | Ability to use email address as user name | ✔ | ✔ | | [XEP-0114](http://xmpp.org/extensions/xep-0114.html?ref=process-one.net) | Jabber Component Protocol | Plugin-like interface for server-side software components | ✔ | ✔ | | [XEP-0115](http://xmpp.org/extensions/xep-0115.html?ref=process-one.net) | Entity Capabilities | Discovery of client capabilities | ✔ | ✔ | | [XEP-0124](http://xmpp.org/extensions/xep-0124.html?ref=process-one.net) | Bidirectional-streams Over Synchronous HTTP (BOSH) | Long polling technique for web clients (HTTP Binding) | ✔ | ✔ | | [XEP-0133](http://xmpp.org/extensions/xep-0133.html?ref=process-one.net) | Service Administration | Server message broadcast and client-side server configuration | ✔ | ✔ | | [XEP-0138](http://xmpp.org/extensions/xep-0138.html?ref=process-one.net) | Stream Compression | Limit bandwith consumption used by XMPP protocole | ✔ | ✔ | | [XEP-0153](http://xmpp.org/extensions/xep-0153.html?ref=process-one.net) | vCard-Based Avatars | Communicating user avatar information | ✔ | ✔ | | [XEP-0156](http://xmpp.org/extensions/xep-0156.html?ref=process-one.net) | Discovering Alternative XMPP Connection Methods | Discover alternative methods of connecting to an XMPP server via Web Host Metadata Link format | ✔ | ✔ | | [XEP-0157](http://xmpp.org/extensions/xep-0157.html?ref=process-one.net) | Contact Addresses for XMPP Services | Discover server admin contact detail | ✔ | ✔ | | [XEP-0158](http://xmpp.org/extensions/xep-0158.html?ref=process-one.net) | CAPTCHA Forms | Additional security to prevent bot massive operations | ✔ | ✔ | | [XEP-0160](http://xmpp.org/extensions/xep-0160.html?ref=process-one.net) | Best Practices for Handling Offline Messages | Best practices to be followed by Jabber/XMPP servers in handling messages sent to recipients who are offline | ✔ | ✔ | | [XEP-0163](http://xmpp.org/extensions/xep-0163.html?ref=process-one.net) | Personal Eventing Protocol | Personal events like location, mood, activity, etc. | ✔ | ✔ | | [XEP-0170](http://xmpp.org/extensions/xep-0170.html?ref=process-one.net) | Recommended Order of Stream Feature Negotiation | Recommended order for negotiation of XMPP stream features | ✔ | ✔ | | [XEP-0175](http://xmpp.org/extensions/xep-0175.html?ref=process-one.net) | Best Practices for Use of SASL ANONYMOUS | Authentication method for user without account | ✔ | ✔ | | [XEP-0176](http://xmpp.org/extensions/xep-0176.html?ref=process-one.net) | Jingle ICE-UDP Transport Method | Technique for NAT traversal, see STUN and TURN(VoIP and binary exchanges) | ✔ | ✔ | | [XEP-0178](http://xmpp.org/extensions/xep-0178.html?ref=process-one.net) | Best Practices for Use of SASL EXTERNAL | Authentication method | ✔ | ✔ | | [XEP-0185](http://xmpp.org/extensions/xep-0185.html?ref=process-one.net) | Dialback Key Generation and Validation | Method for generating and validating the keys used in the XMPP server dialback protocol | ✔ | ✔ | | [XEP-0191](http://xmpp.org/extensions/xep-0191.html?ref=process-one.net) | Simple Communication Blocking | Simple messages blocker | ✔ | ✔ | | [XEP-0198](http://xmpp.org/extensions/xep-0198.html?ref=process-one.net) | Stream Management | XMPP protocol extension for active management of an XML stream between two XMPP entities | ✔ | ✔ | | [XEP-0199](http://xmpp.org/extensions/xep-0199.html?ref=process-one.net) | XMPP Ping | A ping technique specific to XMPP | ✔ | ✔ | | [XEP-0202](http://xmpp.org/extensions/xep-0202.html?ref=process-one.net) | Entity Time | To query one's entity local time | ✔ | ✔ | | [XEP-0203](http://xmpp.org/extensions/xep-0203.html?ref=process-one.net) | Delayed Delivery | Offline message timestamp | ✔ | ✔ | | [XEP-0205](http://xmpp.org/extensions/xep-0205.html?ref=process-one.net) | Best Practices to Discourage Denial of Service Attacks | Best Practices to Discourage Denial of Service Attacks plus other protection mechanisms | ✔ | ✔ | | [XEP-0206](http://xmpp.org/extensions/xep-0206.html?ref=process-one.net) | XMPP Over BOSH | For web-based client, long-polling technique | ✔ | ✔ | | [XEP-0215](http://xmpp.org/extensions/xep-0215.html?ref=process-one.net) | External Service Discovery | Discovery of extra-services addresses (TURN,...) | ✔ | ✔ | | [XEP-0220](http://xmpp.org/extensions/xep-0220.html?ref=process-one.net) | Server Dialback | Workflow to use when dialbacking | ✔ | ✔ | | [XEP-0223](http://xmpp.org/extensions/xep-0223.html?ref=process-one.net) | Persistent Storage of Private Data via PubSub | Use PubSub to store private information | ✔ | ✔ | | [XEP-0227](http://xmpp.org/extensions/xep-0227.html?ref=process-one.net) | Portable Import/Export Format for XMPP-IM Servers | Import/Export for server data | ✔ | ✔ | | [XEP-0231](http://xmpp.org/extensions/xep-0231.html?ref=process-one.net) | Bits of Binary | Lightweight method for including small data in an XMPP stanza | ✔ | ✔ | | [XEP-0237](http://xmpp.org/extensions/xep-0237.html?ref=process-one.net) | Roster Versioning | Reduce bandwidth consumption by limiting contact details download | ✔ | ✔ | | [XEP-0248](http://xmpp.org/extensions/xep-0248.html?ref=process-one.net) | PubSub Collection Nodes | Broadcast of pubsub event in a network of pubsub interdependent nodes | ✔ | ✔ | | [XEP-0249](http://xmpp.org/extensions/xep-0249.html?ref=process-one.net) | Direct MUC Invitations | Method for inviting a contact to a multi-user chat room directly, instead of sending the invitation through the chat room | ✔ | ✔ | | [XEP-0279](http://xmpp.org/extensions/xep-0279.html?ref=process-one.net) | Server IP Check | Client can ask server its IP address mostly for VoIP services | ✔ | ✔ | | [XEP-0280](http://xmpp.org/extensions/xep-0280.html?ref=process-one.net) | Message Carbons | Send copy of your own messages to other connected resources | ✔ | ✔ | | [XEP-0288](http://xmpp.org/extensions/xep-0288.html?ref=process-one.net) | Bidirectional Server-to-Server Connections | Protocol for using server-to-server connections in a bidirectional way such that stanzas are sent and received on the same TCP connection | ✔ | ✔ | | [XEP-0313](http://xmpp.org/extensions/xep-0313.html?ref=process-one.net) | Message Archive Management | Protocol to query and control an archive of messages stored on a server | ✔ | ✔ | | [XEP-0317](http://xmpp.org/extensions/xep-0317.html?ref=process-one.net) | Hats | More extensible model for roles and affiliations in Multi-User Chat rooms | ✔ | ✔ | | [XEP-0328](http://xmpp.org/extensions/xep-0328.html?ref=process-one.net) | JID Preparation and Validation Service | A way for an XMPP entity to request another entity to prepare and validate a given JID | ✔ | ✔ | | [XEP-0334](http://xmpp.org/extensions/xep-0334.html?ref=process-one.net) | Message Processing Hints | A way to include hints to entities routing or receiving a message | ✔ | ✔ | | [XEP-0352](http://xmpp.org/extensions/xep-0352.html?ref=process-one.net) | Client State Indication | A way for the client to indicate its active/inactive state | ✔ | ✔ | | [XEP-0355](http://xmpp.org/extensions/xep-0355.html?ref=process-one.net) | Namespace Delegation | A way for XMPP server to delegate treatments for a namespace to an other entity | ✔ | ✔ | | [XEP-0356](http://xmpp.org/extensions/xep-0356.html?ref=process-one.net) | Privileged Entity | A way for XMPP entities to have a privileged access to some other entities data | ✔ | ✔ | | [XEP-0357](http://xmpp.org/extensions/xep-0357.html?ref=process-one.net) | Push Notifications | A way for an XMPP servers to deliver information for use in push notifications to mobile and other devices | ✔ | ✔ | | [XEP-0359](http://xmpp.org/extensions/xep-0359.html?ref=process-one.net) | Unique and Stable Stanza IDs | Generate unique and stable IDs for messages. | ✔ | ✔ | | [XEP-0363](http://xmpp.org/extensions/xep-0363.html?ref=process-one.net) | HTTP File Upload | Protocol to request permissions from another entity to upload a file to a specific path on an HTTP server | ✔ | ✔ | | [XEP-0368](http://xmpp.org/extensions/xep-0368.html?ref=process-one.net) | SRV records for XMPP over TLS | Procedure to look up client and server SRV records (for direct TLS connections) in addition to weights/priorities | ✔ | ✔ | | [XEP-0369](http://xmpp.org/extensions/xep-0369.html?ref=process-one.net) | Mediated Information eXchange (MIX) | Exchange of information among multiple users through a mediating service | ✔ | ✔ | | [XEP-0379](http://xmpp.org/extensions/xep-0379.html?ref=process-one.net) | XEP-0379: Pre-Authenticated Roster Subscription | Facilitate onboarding of new XMPP IM contacts with pre-authenticated roster links | ✔ | ✔ | | [XEP-0384](http://xmpp.org/extensions/xep-0384.html?ref=process-one.net) | OMEMO Encryption | End-to-end encryption in one-to-one chats and MUC rooms | ✔ | ✔ | | [XEP-0386](http://xmpp.org/extensions/xep-0386.html?ref=process-one.net) | Bind 2 | Ssingle-request replacement for several activities an XMPP client needs to do at startup | ✔ | ✔ | | [XEP-0388](http://xmpp.org/extensions/xep-0388.html?ref=process-one.net) | Extensible SASL Profile | Replacement for the SASL profile documented in RFC 6120 which allows for greater extensibility | ✔ | ✔ | | [XEP-0398](http://xmpp.org/extensions/xep-0398.html?ref=process-one.net) | User Avatar to vCard-Based Avatars Conversion | Method for using PEP based avatars and vCard based avatars in parallel by having the user’s server do a conversion between the two | ✔ | ✔ | | [XEP-0401](http://xmpp.org/extensions/xep-0401.html?ref=process-one.net) | Ad-hoc Account Invitation Generation | Facilitate onboarding for XMPP IM newcomers with invitations to account registration. | ✔ | ✔ | | [XEP-0402](http://xmpp.org/extensions/xep-0402.html?ref=process-one.net) | PEP Native Bookmarks | Syntax and storage profile for keeping a list of chatroom bookmarks on the server | ✔ | ✔ | | [XEP-0405](http://xmpp.org/extensions/xep-0405.html?ref=process-one.net) | Mediated Information eXchange (MIX): Participant Server Requirements | Specify behaviour of an XMPP server to which MIX Clients connect in order to enable correct operation of these clients in conjunction with a MIX server | ✔ | ✔ | | [XEP-0410](http://xmpp.org/extensions/xep-0410.html?ref=process-one.net) | MUC Self-Ping (Schrödinger's Chat) | Allow clients to check whether they are still joined to a chatroom | ✔ | ✔ | | [XEP-0411](http://xmpp.org/extensions/xep-0411.html?ref=process-one.net) | Bookmarks Conversion | Method to migrate to PEP based bookmarks without loosing compatibility with client that still use Private XML | ✔ | ✔ | | [XEP-0421](http://xmpp.org/extensions/xep-0421.html?ref=process-one.net) | Anonymous unique occupant identifiers for MUCs | Method that allows clients to identify a MUC participant across reconnects and renames | ✔ | ✔ | | [XEP-0424](http://xmpp.org/extensions/xep-0424.html?ref=process-one.net) | Message Retraction | Method for indicating that a message should be retracted | ✔ | ✔ | | [XEP-0425](http://xmpp.org/extensions/xep-0425.html?ref=process-one.net) | Moderated Message Retraction | Method for groupchat moderators to retract messages of other users | ✔ | ✔ | | [XEP-0431](http://xmpp.org/extensions/xep-0431.html?ref=process-one.net) | Full Text Search in MAM | Extend MAM to perform full text searching | ✔ | ✔ | | [XEP-0440](http://xmpp.org/extensions/xep-0440.html?ref=process-one.net) | SASL Channel-Binding Type Capability | Allow servers to annouce their supported SASL channel-binding types to clients | ✔ | ✔ | | [XEP-0441](http://xmpp.org/extensions/xep-0441.html?ref=process-one.net) | Message Archive Management Preferences | Protocol to control a user's archiving preferences. | ✔ | ✔ | | [XEP-0445](http://xmpp.org/extensions/xep-0445.html?ref=process-one.net) | Pre-Authenticated In-Band Registration | Extend In-Band Registration protocol to support invitation tokens. | ✔ | ✔ | | [XEP-0474](http://xmpp.org/extensions/xep-0474.html?ref=process-one.net) | SASL SCRAM Downgrade Protection | A way to secure the SASL and SASL2 handshakes against method and channel-binding downgrades | ✔ | ✔ | | [XEP-0480](http://xmpp.org/extensions/xep-0480.html?ref=process-one.net) | SASL Upgrade Tasks | A way to upgrade to newer SASL mechanisms using SASL2 tasks | ✔ | ✔ | | [XEP-0484](http://xmpp.org/extensions/xep-0484.html?ref=process-one.net) | Fast Authentication Streamlining Tokens | Allow clients fully authenticated stream establishment within a single round-trip | ✔ | ✔ | | [XEP-0485](http://xmpp.org/extensions/xep-0485.html?ref=process-one.net) | PubSub Server Information | Data format whereby basic information of an XMPP domain can be expressed and exposed over PubSub | ✔ | ✔ | | [XEP-0486](http://xmpp.org/extensions/xep-0486.html?ref=process-one.net) | MUC Avatars | How to publish and retrieve avatars in rooms | ✔ | ✔ | ## Business-Edition XMPP Extensions | RFC | Title | Description | Community Server (eCS) | Business Edition (eBE) | | ------------------------------------------------------------------------ | ------------------------- | ------------------------------------------------------------------------------------------------ | ---------------------- | ---------------------- | | [XEP-0020](http://xmpp.org/extensions/xep-0020.html?ref=process-one.net) | Feature Negotiation | Discovery of component feature | ✘ | ✔ | | [XEP-0142](http://xmpp.org/extensions/xep-0142.html?ref=process-one.net) | Workgroup Queues | Enables a user to communicate with a representative of an organization, department, or workgroup | ✘ | ✔ | | [XEP-0172](http://xmpp.org/extensions/xep-0172.html?ref=process-one.net) | User Nickname | Nickname metadata | ✘ | ✔ | | [XEP-0225](http://xmpp.org/extensions/xep-0225.html?ref=process-one.net) | Component Connections | New protocol to connect components to XMPP servers | ✘ | ✔ | | [XEP-0256](http://xmpp.org/extensions/xep-0256.html?ref=process-one.net) | Last Activity in Presence | Method for determining the last time that an XMPP entity was active | ✘ | ✔ | ## External IETF Specifications (non-XMPP) | RFC | Title | Description | Community Server (eCS) | Business Edition (eBE) | | -------- | ------------------------------------------------------------ | ------------------------------------------------------------------ | ---------------------- | ---------------------- | | RFC-5802 | Salted Challenge Response (SCRAM) SASL and GSS-API Mechanism | Secure authentication methods | SCRAM only | | | RFC-5766 | Session Traversal Utilities for NAT (STUN) | Technique for easier binary session parameters negotiation | ✔ | ✔ | | RFC-5766 | Traversal Using Relays around NAT (TURN) | Technique for binary data relay | ✘ | ✔ | | RFC-5245 | Interactive Connectivity Establishment (ICE) | Technique mixing STUN and TURN | ✘ | ✔ | | RFC-6455 | The WebSocket protocol | For web-based clients, real time bidirectional in-browser protocol | ✔ | ✔ | ## Performance and Scalability | RFC | Title | Description | Community Server (eCS) | Business Edition (eBE) | | ------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | ---------------------- | | P1-Spec | Clustering | Unique clustering mode with no single point of failure. This is true active - active service for scalability and fault-tolerance | ✔ | ✔ | | P1-Spec | Consistent hash clustering | Low latency, higher performance clustering method to build large scale platform | ✘ | ✔ | ## Security | RFC | Title | Description | Community Server (eCS) | Business Edition (eBE) | | ------- | --------------- | ---------------------------------------------------------------------------------------------------- | ---------------------- | ---------------------- | | P1-Spec | Traffic shapers | Comprehensive policy for limiting, managing, and optimizing incoming traffic bandwidth on the server | ✔ | ✔ | ## Mobile | RFC | Title | Description | Community Server (eCS) | Business Edition (eBE) | | ------- | --------------------------- | ------------------------------------------------------------------------------------------------- | ---------------------- | ---------------------- | | P1-Spec | Out-of-reception state | Mechanism to keep connection state on the server side, independently of the current network state | ✘ | ✔ | | P1-Spec | Fast reconnect ("rebind") | Mechanism to reattach to an existing session when mobile is getting reconnected on the network | ✘ | ✔ | | P1-Spec | GCM & Firebase push | Message notification for Android devices | ✘ | ✔ | | P1-Spec | Apple push | Message notification for iOS devices | ✘ | ✔ | | P1-Spec | Acknowledgements and replay | Message reliability: no message can be lost even under network inconsistencies | ✘ | ✔ | | P1-Spec | End-to-end traceability | Message indicator (status: sent, delivered, offline, which server has been reached...) | ✘ | ✔ | | P1-Spec | Multi-device and archiving | Message replication and synchronization across devices | ✘ | ✔ | ## Posts ### ejabberd 26.07 URL: https://www.process-one.net/blog/ejabberd-26-07/ Last updated: 2026-07-31T13:00:50.000Z **Contents:** - **[Changes in SQL schemas](#sql)** - **[Security fixes](#security)** - **[mod\_invites: New pages to create invites, reset password command and WebAdmin](#mod%5Finvites)** - **[mod\_conversejs: Support ConverseJS 14](#converse)** - **[Erlang/OTP 27.0 as a soft minimum](#erlang)** - **[Rebar/Rebar3: Update binaries to work with Erlang/OTP 26-29](#rebar)** - **[ChangeLog](#changelog)** - **[Acknowledgments](#ack)** - **[Improvements in ejabberd Business Edition](#ebe)** - **[fluux.io](#fluux)** - **[ejabberd 26.07 download & feedback](#download)** ## Changes in SQL schema If you upgrade ejabberd from a previous release to [26.07](https://docs.ejabberd.im/archive/26.07/?ref=process-one.net), there are no changes in SQL schemas, but there is one for ejabberd Business Edition (see [below](#sqlebe)). ## Security fixes This release contains fixes for those security issues: - It's possible to craft PLAIN auth request and authenticate as one user, but then open session for different one. - `mod_caps` persistent cache can be poisoned by using legacy version requests.This cache was only used to determine list of nodes that should trigger notifications in PubSub presence-based delivery. - SQL injection in `mod_pubsub` handling of paging requests. - Possible atom exhaustion that can be triggered by issuing REST requests to `mod_http_api`. - It was possible to make ejabberd send redirect response for OAuth requests to unvetted url. This required enabling ejabberd to act as OAuth provider (by adding request handler for `ejabberd_oauth` in http listener). As part of this fix we changed `oauth_client_id_check` default value to `db`. - using ejabberd as OAuth provider will be only allowed by clients that were previously registered with `oauth_add_client_password` or `oauth_add_client_implicit` commands. - Tokens generated by `mod_bosh`, `captcha`, `mod_auth_fast`, `mod_http_upload` and `mod_invites` used not cryptographically strong random number generators. - Files server by `mod_http_upload` didn't have XSS prevention headers. - Issues in authentication of SIP requests. - Request to web\_admin were lacking CSRF protection. - It was possible to skip captcha verification in mod\_register\_web. - `mod_conversejs` allowed putting unescaped value from url in page content. ## mod\_invites: New pages to create invites and WebAdmin [mod\_invites](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Finvites) now includes a startpage where regular users can use their account credentials to generate new account creation invites. This is useful for people using XMPP clients that do no support that feature. The URL of that page is the root of mod\_invites; you can find a link to that page in the bottom of WebAdmin left menu. There are also new WebAdmin pages to view the existing invites, generate new invites, expire, delete ... Go and take a look at WebAdmin > "Virtual Hosts" > one of your hosts > "Invites" There is also a new command [generate\_reset\_token](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#generate%5Freset%5Ftoken) that returns an URI with a password reset token, just like for the invite tokens. This functionnality can also be found in the WebAdmin. ## mod\_conversejs: Support ConverseJS 14 [ConverseJS](https://conversejs.org/?ref=process-one.net) published version [14.0.0](https://github.com/conversejs/converse.js/releases/tag/v14.0.0?ref=process-one.net) recently, and it requires some changes in the web server. In this sense, [mod\_conversejs](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fconversejs) is updated to support ConverseJS 14, and also got other minor cosmetic improvements. ## Erlang/OTP 27.0 as a soft minimum Are you compiling ejabberd with [Erlang/OTP](https://www.erlang.org/?ref=process-one.net) 25 or 26? Then please try to update to Erlang/OTP 27, 28, or 29\. For example, the ejabberd installers are compiled with Erlang/OTP 28.5.0.4. ejabberd supports compilation with Erlang/OTP 25 and 26, and those versions are still tested in [runtime.yml](https://github.com/processone/ejabberd/blob/master/.github/workflows/runtime.yml?ref=process-one.net) and [weekly.yml](https://github.com/processone/ejabberd/blob/master/.github/workflows/weekly.yml?ref=process-one.net), but those Erlang/OTP versions are not actively maintained anymore by Erlang/OTP. Following the erlang security recommendation to [Use Actively Maintained Versions of Erlang/OTP](https://www.erlang.org/doc/system/secure%5Fcoding.html?ref=process-one.net#rule-dep-003), from now ejabberd *softly* rejects compilation with Erlang/OTP lower than 27. What does *softly* mean? If you really want to compile ejabberd with Erlang/OTP lower than 27 at your own risk, you can bypass that soft requirement by defining this option (Erlang/OTP 25.0 included [Erlang Run-Time System 13.0](https://www.erlang.org/docs/25/apps/erts/notes.html?ref=process-one.net#erts-13.0), and that is the number to provide in that option): ```sh ./configure --with-min-erlang=13.0 ``` ## Rebar/Rebar3: Update binaries to work with Erlang/OTP 26-29 ejabberd source code includes [Rebar](https://github.com/rebar/rebar?ref=process-one.net) and [Rebar3](https://rebar3.org/?ref=process-one.net) binaries, in case you don't have installed in your system. But those programs only support four Erlang releases (26 up to 29). If you want to compile ejabberd with Erlang 25, then you need to grab a compatible Rebar3 (or Rebar) binary: either install one from your operating system, or you can download the old binaries included with ejabberd 26.04 (those still supported Erlang 25): ``` https://github.com/processone/ejabberd/raw/26.04/rebar https://github.com/processone/ejabberd/raw/26.04/rebar3 ``` ## ChangeLog #### Security fixes This release contains fixes for those issues: - It's possible to craft PLAIN auth request and authenticate as one user, but then open session for different one. - mod\_caps persistent cache can be poisoned by using legacy version requests. This cache was only used to determine list of nodes that should trigger notifications in PubSub presence-based delivery. - SQL injection in mod\_pubsub handling of paging requests. - Possible atom exhaustion that can be triggered by issuing REST requests to mod\_http\_api - It was possible to make ejabberd send redirect response for OAuth requests to unvetted url. This required enabling ejabberd to act as OAuth provider (by adding request handler for ejabberd\_oauth in http listener). As part of this fix we changed `oauth_client_id_check` default value to `db` - using ejabberd as OAuth provider will be only allowed by clients that were previously registered with `oauth_add_client_password` or `oauth_add_client_implicit` commands. - Tokens generated by mod\_bosh, captcha, mod\_auth\_fast, mod\_http\_upload and mod\_invites used not cryptographically strong random number generators. - Files server by mod\_http\_upload didn't have XSS prevention headers. - Issues in authentication of SIP requests. - Request to web\_admin were lacking CSRF protection. - It was possible to skip captcha verification in mod\_register\_web. - mod\_conversejs allowed putting unescaped value from url in page content. #### Core - Fixes `delete_old_messages_batch` command when used on pgsql - Adds `export_db_ext` which allows exporting db content to json files - Use constant time functions when doing password checks - Optimize `room_unused_*` commands when room hibernation is configured - We no longer add flag requesting client certificate for tls connections where certificate authentication is not enabled #### Modules - `mod_auth_fast`: Fixes exception for session that didn't set user agent - `mod_invites`: Add page for creating invites. - `mod_invites`: Fix generation of CSRF tokens. - `mod_invites`: Update to changes in latest XEP-0401 - `mod_http_upload`: Attach custom headers from config when serving files. ### Full Changelog [https://github.com/processone/ejabberd/compare/26.04...26.07](https://github.com/processone/ejabberd/compare/26.04...26.07?ref=process-one.net) ## Acknowledgments We would like to thank for the security reports provided by: - [arthurscchan](https://github.com/arthurscchan?ref=process-one.net) - [EkiXu](https://github.com/EkiXu?ref=process-one.net) - [kah-ja](https://github.com/kah-ja?ref=process-one.net) - [LautaroPetaccio](https://github.com/LautaroPetaccio?ref=process-one.net) - Marius Schwarz - [tinyb0y](https://github.com/tinyb0y?ref=process-one.net) - [X1AOxiang](https://github.com/X1AOxiang?ref=process-one.net) the contributions to the source code by: - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for the new features, improvements and fixes in `mod_invites` - [Christian Dröge](https://github.com/cdroege?ref=process-one.net) - [Holger Weiß](https://github.com/weiss?ref=process-one.net) - [Jonathan Davies](https://github.com/jpds?ref=process-one.net) - [Kirill A. Korinsky](https://github.com/catap?ref=process-one.net) and the translation by: - [Mr. EddX](https://github.com/MrEddX?ref=process-one.net) for updating the Bulgarian translation - [Arif Budiman](https://github.com/arifpedia?ref=process-one.net) for updating the Indonesian translation - [TamilNeram](https://github.com/TamilNeram?ref=process-one.net) for updating the Tamil translation And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/compare/), in addition to all those bugfixes, also get the following changes: ### Changes in SQL schema This release modifies the `push_customizations` table in the SQL database schemas to support the new push notifications mute option (see [below](#push)). This task is performed automatically by ejabberd by default. However, if your configuration file has disabled [update\_sql\_schema](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#update%5Fsql%5Fschema) toplevel option, you must perform the SQL schema update manually yourself. Those instructions are valid for MySQL and PostgreSQL, both default and new schemas: #### MySQL ```sql ALTER TABLE push_customizations MODIFY COLUMN mute smallint; ``` #### PostgreSQL ```sql ALTER TABLE push_customizations ALTER COLUMN mute TYPE smallint USING mute::int; ``` ### Push notifications - Add a push customization option to allow mentioned users (as described in [XEP-0513](https://xmpp.org/extensions/xep-0513.html?ref=process-one.net)) to be notified even in muted conversation. - Make proxy connections in applepushv3 always use http connect - Report push gate tokens in the results of the `user_push_state` command - Implement push errors reporting in the results of the `user_push_state` command. - Make `mod_webpush` reject tokens that don't have correct format. - Fix `mod_webpush` key parser. - Add ability to retrieve user nodes from push\_gate. - Handle wildcard certificates now used by Google FCM service. ### Commands Add a new `local_health_status` command to return information about local node state. ### Client certificate authentication - Add option `require_xmpp_addr` that forces client certs to have `XmppAddr`. - New `recognize_email_addr` option for `mod_crl`/`mod_ocsp` to add `emailAddress` from cert subject to be used beside `xmppAddr` for matching against provided user id. ### p1db backend - Make `mam_p1db` serialization properly serialize MUC archives. - Fix JID encoding in `roster_p1db` serialization. - Fix decoding of `fast_tokens` in p1db backend ### Clustering Make `join_cluster` robust to race conditions on `leave_cluster`. ### Docker sqlite backend has been fixed in Docker image. ## fluux.io All [fluux.io](http://fluux.io/?ref=process-one.net) instances have been updated before the release of the 26.07 with the latest security fixes. ## ejabberd 26.07 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/download/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying-process-one-downloads-integrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Fluux Messenger 0.17.2: gapless history, faster transfers, and emoji autocomplete URL: https://www.process-one.net/blog/fluux-messenger-0-17-2-gapless-history-faster-transfers-and-emoji-autocomplete/ Last updated: 2026-07-21T12:21:38.000Z ## History without gaps The largest piece of work in this release is the kind you only notice when it is absent. - **Interrupted archive syncs now heal.** If a sync of the message archive (XEP-0313) was cut short, a conversation could be left with a silent gap: messages that were never fetched, and nothing on screen to say anything was missing. Interruptions are now detected and repaired from both directions. - **History no longer depends on your read position.** Opening a conversation you had already read elsewhere could show an empty history on a new or freshly cleared device. The archive now downloads independently of how far you had read. - **A conversation read on another device opens at its live edge**, instead of restoring a saved scroll position that multi-device sync had already made obsolete. - **The new-messages divider and the unread badge** on the scroll-to-bottom button follow your read position, consistent with the sidebar and with read-marker sync (XEP-0490). These are the paths we found and could reproduce. Archive sync has a long tail, and how it behaves depends a good deal on which server you are talking to. If you still see a conversation with history missing, we would love to hear about it. ## Faster file transfers - **Desktop uploads and downloads are handled by native code.** Transfers of large files are much faster and more reliable. - **Encrypted attachments decrypt on download.** An end-to-end-encrypted attachment used to be decrypted only for the inline preview, so saving it to disk gave you something unreadable. Files of every type now arrive readable. ## Emoji autocomplete & polish - **Type a colon and a keyword** to complete emoji inline. Arrow keys move through the matches, Enter or Tab inserts. - **The send button** answers with a press and a glow pulse when a message goes out. ## On the web - **An unread badge on the app icon** for the installed PWA. - **Media is cached by the service worker**, so images are not re-downloaded on every visit. - **Repeated messages from one sender** coalesce into a single "N new messages" notification instead of a stack. - **An update that was downloaded but parked** is now applied at launch, instead of the installed app trailing the deployed build indefinitely. ## Reliability and platform fixes Twenty-three fixes in this release. The ones most likely to have affected you: - **Notifications behave.** Clicking a reaction notification always jumps to the reacted message, reopening a conversation no longer re-posts a notification for something you have already seen, and an encrypted message with no readable content stays silent until it is decrypted instead of posting a blank notification and playing a sound. - **The sidebar holds still.** A delayed message, whether an offline replay or a catch-up copy older than what you already have, no longer drags the conversation preview back to older text. The sidebar also keeps its scroll position while conversations reorder during catch-up. - **Authentication.** A wrong saved password no longer triggers an endless keychain retry loop, and connecting to a server whose domain contains non-ASCII characters now works. - **Key backup.** The backup passphrase is used exactly as it is displayed, so backups restore in other XMPP clients. Older backups still open, and are healed to the portable format on restore. - **Group chats.** The public room directory no longer lists duplicate rooms or reaches past your server's own directory, and a room notification banner no longer reappears when the room is reopened. Smaller ones round out the release: the quoted-message and reply cards stay visually distinct when a message is selected, your own message group re-fits its width once an image inside it finishes loading, the typing indicator is centered between the last message and the composer, and the macOS traffic-light buttons stay centered in the app bar. ## Get it [Fluux Messenger 0.17.2](https://www.process-one.net/fluux-messenger/) is available for macOS, Windows, and Linux, or directly in your browser. If you upgrade and something feels off, tell us. Bug reports and feature requests both go to [GitHub Issues](https://github.com/processone/fluux-messenger/issues?ref=process-one.net). ### Fluux Messenger 0.17.1: improved read sync, a Pure theme, and Aurora refinements URL: https://www.process-one.net/blog/fluux-messenger-0-17-1-improved-read-sync-a-pure-theme-and-aurora-refinements/ Last updated: 2026-07-13T13:19:54.000Z ## Read state that actually syncs 0.17.0 introduced synced read markers (XEP-0490), but we shipped a bug: the payload we published used the wrong shape, so other XMPP clients ignored our read state, and we ignored theirs. 0.17.1 sets this right: - **Spec-accurate XEP-0490 payloads.** Fluux now publishes the shape other clients expect, and migrates the legacy markers 0.17.0 wrote. - **Notifications follow your reading.** When you read a conversation on one device, its native notification banner is dismissed on your other devices. Read markers synced while a room was inactive are now applied too. - **Your place is kept.** A room no longer discards your read position on launch. Fluux anchors on the last-read message, the way other modern chat apps do, and the marker advances correctly once you reach the live edge of a conversation. ## A Pure theme for OLED and e-ink New in this release: the **Pure theme**, in pure-black and pure-white variants. Flat, high-contrast chrome with no gradients or translucency, designed for OLED displays and e-ink screens. There is also a new **"Play notification sounds"** toggle in Accessibility settings. ## Group chats - **Slash commands in the composer**, including `/nick` to change your nickname. The change is reflected in the occupant list and as a timeline notice. - **Typing indicator in the sidebar** for joined rooms. It only appears when a caught-up room lights up; busy or unread rooms keep their badge. - **Impersonation hardening.** Nicknames padded with whitespace or invisible characters can no longer masquerade as another occupant. ## Aurora refinements - **Shields and locks now mean different things.** A shield shows encryption status; a lock is reserved for content that cannot be read. The two metaphors are applied consistently across the chat header, message indicators, composer, and security panel. - **Cleaner outgoing bubbles.** Consecutive messages you send hug their content and form clean rectangular groups. - **Calmer motion.** Space is reserved for the typing indicator so it no longer overlays the last message or fights an upward scroll, and Aurora gradients now harmonize with your accent color in each theme. ## Reliability and platform fixes - **Jumps always land.** Jumping to a reacted, replied-to, or poll message works even when the target is outside the loaded history window, and search previews stay centered on the match. - **Linux.** The system tray dependency is standardized on libayatana-appindicator so tray menu labels render, Flatpak installs auto-pull the GNOME runtime, and modals stay solid where WebKitGTK advertises backdrop blur it does not actually paint. - **Link previews** are now attached in the interoperable OGP format, so other XMPP clients display them correctly. The full list of changes is in the [changelog on GitHub](https://github.com/processone/fluux-messenger/releases?ref=process-one.net). ## Get it [Fluux Messenger 0.17.1](https://www.process-one.net/fluux-messenger/) is available for macOS, Windows, and Linux, or directly in your browser. As always, it works with any standards-compliant XMPP server, and it remains our day-to-day client at ProcessOne. If you upgrade and something feels off, tell us. A lot of what shipped in this release started as a user report — bugs and ideas are welcome on [GitHub Issues](https://github.com/processone/fluux-messenger/issues?ref=process-one.net). ### Fluux Messenger 0.17.0: Aurora, a new visual identity and conversation-first navigation URL: https://www.process-one.net/blog/fluux-messenger-0-17-0-aurora-a-new-visual-identity-and-conversation-first-navigation/ Last updated: 2026-07-06T12:18:06.000Z ## Aurora: a new identity for Fluux Fluux has a new face. The app icon, logo, and the entire interface have been redesigned around Aurora, a teal-to-violet gradient identity with display headings, softer avatar shapes, and frosted-glass modals. Aurora is more than a color swap: - **Per-person sender colors.** Each participant in a group chat gets a stable, readable color, tuned for WCAG AA contrast in both light and dark themes. - **Curated accent presets.** Pick the accent that suits you; the whole interface follows, including the encryption affordances, which now use one consistent color from the chat header to the message locks and the composer. - **Calmer chrome.** Thinner scrollbars, consistent focus rings, quieter notification badges. Unread indicators now follow a simple two-tier model: red means something needs you (a direct message, a mention, a contact request), grey means ambient room activity. If you preferred the previous color scheme, it is still there as the “Indigo classic” theme. ## Conversation-first navigation We removed the standalone Events view. It was a place you had to remember to check; now events come to you, in context: - Contact requests, room invitations, and message requests appear as headed sections at the top of the relevant lists. - A message from someone not in your roster opens as a read-only preview with an Accept / Ignore / Block banner, so you can see what it is before you commit to anything. - Contacts moved down to the navigation cluster, with a badge when requests are pending. - Archived conversations are one toggle away in the Messages header, and archiving now syncs live across your devices. The result is fewer top-level destinations and less bookkeeping. ## Jump anywhere with the command palette Press Cmd-K (Ctrl-K on Windows and Linux) to jump to any conversation or action. The palette puts your unread chats and mentioned rooms first, shows avatars and unread badges, and never proposes the conversation you are already reading. ## Unlimited scroll-back The fixed 1,000-message cap on conversation history is gone. History is now a sliding window: scroll back as far as you like, and messages load incrementally from the local cache and the server archive (MAM). Combined with message-list virtualization, now on by default, long conversations stay fast, and typing no longer reflows the message list on every keystroke. While we were in there, we fixed a long tail of scroll issues: new messages reliably stick to the bottom on WebKit, returning to a conversation restores exactly where you were reading (even deep in history), and jumping to a search result lands the message a third of the way down the viewport instead of hiding it under the date header. ## Your reading position follows you Read markers now sync across devices (XEP-0490). If you read a conversation on your desktop, it opens at the right position on your laptop, and its notification is dismissed. Together with live archive sync and the carbons and MAM work from previous releases, your devices now agree on what you have read, what is pending, and what is filed away. ## A friendlier admin console For those who administer their own ejabberd server, the ad-hoc command list is gone, replaced by purpose-built screens: a server overview dashboard, a searchable user list with online status and last login, a redesigned user detail view with a Ban account action, and a mobile launchpad. Only a few server admin commands are available so far, but we plan to grow the list with each new version. ## Desktop and everyday polish - **Window app bar.** The desktop app gets back/forward navigation in a proper window bar, with correctly centered traffic lights on macOS. - **Calm updates.** Instead of reloading the app under your feet, a new “Update available” button appears in the icon rail when a new version is ready. You decide when. - **Reduce motion.** A new accessibility setting minimizes animations and follows your system preference. - **Advanced mode.** The XMPP console and expert settings are now behind an in-app toggle, keeping the default settings approachable. - **Redesigned contact details.** A person-forward view with cards for devices, groups, and security, and fingerprint verification in its own focused panel. ## And the usual pile of fixes Almost 300 commits went into this release, so the full list is long. Some favorites: your own encrypted messages now show their real trust level instead of a grey lock under some circumstances; whispers in group chats keep their corrections and reactions private; animated avatars are frozen so they stop competing for your attention, even if they are PNGs; reactions from ignored users are hidden; and rooms are sorted correctly the moment the app launches. The complete list is in the [changelog](https://github.com/processone/fluux-messenger/releases/tag/v0.17.0?ref=process-one.net). ## Try it [Fluux Messenger 0.17.0](https://www.process-one.net/download/fluux-messenger/) is available for macOS, Windows, and Linux, or directly in your browser. As always, it works with any standards-compliant XMPP server, and it remains our day-to-day client at ProcessOne. If you upgrade and something feels off, tell us. A lot of what shipped in this release started as a user report. ### Fluux Messenger 0.16.1: fixes and refinements from real-world use URL: https://www.process-one.net/blog/fluux-messenger-0-16-1-fixes-and-refinements-from-real-world-use/ Last updated: 2026-06-16T14:23:59.000Z 0.16.1 is our quick turnaround on that: a focused round offixes for the issues that have been reported, across encryption, connectivity,message history, and the desktop apps. Nothing dramatic here, we mainly want to show that we're listening and addressing reported problems fast. ## End-to-end encryption in daily use With people now encrypting real conversations, a few practical details surfaced —and they're sorted: - **Verification works across clients.** Fingerprints are published and compared in a consistent case (XEP-0373 expects upper-case), so the green "verified" lock appears reliably whatever XMPP client your contact uses. - **Cleaner previews and placeholders.** Encrypted reactions now show up properly in the conversation list, and you'll see a "decrypting…" placeholder while the encryption plugin finishes loading. - **Complete archive.** Encrypted messages without a plaintext body now come through correctly from server history (MAM). ## Smoother connections Field reports pointed to a handful of connection scenarios, now improved: - **Happy Eyeballs.** Fluux races IPv4 and IPv6 when connecting, so a slow or broken IPv6 route no longer holds things up, whichever answers first wins. - **More reliable reconnection.** Stream Management handling and the desktop's local proxy hop were both tuned to resolve reconnection cases users reported. - **Clearer status.** Presence pills stay grey while reconnecting, and the reconnect spinner and countdown are back in the sidebar status chip for a calmer interface on unstable networks. ## More complete message history - **Gap recovery.** Some users reported missing stretches of history after long periods offline. Catch-up now closes those gaps in both group chats and 1:1 conversations, with a "load missing messages" marker to bring back anything that was skipped. - **Reliable scroll-up.** Loading older history by scrolling up now works as expected. ## A more polished desktop experience - **Notifications open the right chat.** On macOS, clicking a notification takes you straight to the conversation it belongs to. - **Single window.** Relaunching the app focuses the window that's already running instead of opening a second copy. - **Linux tray fallback.** When the system tray isn't available, closing the window quits the app, so it can always be reopened. - Image downloads use the native save dialog, and Settings now links straight to your system notification settings. ## Lots of smaller fixes And plenty of smaller refinements from everyday use: consistent empty-state icons, reply quotes that match the original sender's color and render as nested bars, opening a contact profile no longer bouncing you back, link-preview images that retry once before hiding, a smoother composer resize, local JID validation on the login screen, and group-chat performance improvements on room join. --- Thanks to everyone who reported issues and shared feedback – that's exactly what shapes a release like this one. [0.16.1 is available now on our website](https://www.process-one.net/fluux-messenger/), and the full changelog is on [GitHub](https://github.com/processone/fluux-messenger/blob/main/CHANGELOG.md?ref=process-one.net). Keep the reports coming! ### Fluux Messenger 0.16.0: End-to-End Encryption URL: https://www.process-one.net/blog/fluux-messenger-0-16-0-end-to-end-encryption/ Last updated: 2026-06-11T11:08:12.000Z Beyond that headline, the release also ships whisper messages, offline compose, unread badges, and a significant render-performance pass. Here is what changed and why. ## End-to-End Encryption with OpenPGP When end-to-end encryption is on, your messages are scrambled on your device before they leave it. Your XMPP server relays ciphertext, but it cannot read your conversations, even if the server is compromised or an administrator goes looking. The same applies to any relay between servers. Fluux implements **OpenPGP for XMPP** ([XEP-0373](https://xmpp.org/extensions/xep-0373.html?ref=process-one.net), also called *OX*) — the modern redesign of OpenPGP encryption for XMPP. If you have come across [XEP-0027](https://xmpp.org/extensions/xep-0027.html?ref=process-one.net) (the older "Current Jabber OpenPGP Usage"), that is a different, now-deprecated approach with well-documented weaknesses: no authenticated message envelope, signed-plaintext exposure, and no multi-device story. Fluux implements XEP-0373 only. It uses a proper content-encryption layer ([XEP-0420](https://xmpp.org/extensions/xep-0420.html?ref=process-one.net)) that authenticates the full message context and hides metadata from the server. It builds on the same OpenPGP cryptography used in encrypted email for decades, adapted correctly to instant messaging. ![](https://www.process-one.net/content/images/2026/06/25-chat-encrypted-dark.png) Once you enable encryption in **Settings → Encryption**, your key pair is generated and your public key is published to your server. From that point, whenever a contact also has encryption enabled, Fluux automatically starts encrypting messages to them. A **lock icon** above the composer confirms it. Nothing to configure per conversation. Encrypted messages cover more than just text: reactions, edits, retractions, link previews, and file attachments all ride inside the same encrypted envelope. The server cannot see which emoji you reacted with, what you edited a message to say, or which files you shared. ## Why OpenPGP first? The choice of OpenPGP as the first E2EE protocol was deliberate, and it comes down to four practical properties. **Multi-device without friction.** A single OpenPGP key pair works across all your devices. You generate it once; every device you add simply loads the same key. There is no per-device key negotiation, no session bootstrapping required before encrypted history loads. This stands in contrast to ratchet-based protocols that issue a key per client installation and require all clients to exchange session state before decryption is possible. **Encrypted backup you control.** When you click **Back up** in the encryption settings, Fluux generates a **backup code** — 24 upper-case characters drawn from an unambiguous alphabet (no `O` or `0`), grouped into 4-character chunks with dashes (e.g. `TWNK-KD5Y-MT3T-E1GS-DRDB-KVTW`). This format follows XEP-0373 §5.4 and is accepted by other compliant clients such as Gajim. Fluux encrypts your secret key with this code and stores the encrypted blob on your own XMPP server under a private node only you can access. The code never leaves your device. ![](https://www.process-one.net/content/images/2026/06/26-settings-encryption-dark.png) **Your full history stays readable.** Because every device shares the same key, messages encrypted months ago on one device remain decryptable on another. The server's message archive ([MAM](https://xmpp.org/extensions/xep-0313.html?ref=process-one.net)) becomes a true history, not a graveyard of ciphertext only the originating device can open. Outgoing messages are also encrypted to your own key, so your sent history is fully accessible on every device. **Simple, comprehensible verification.** Trust On First Use (TOFU) gives you safe, convenient defaults. When you want a stronger guarantee, you compare fingerprints out-of-band, i.e. in person, over a phone call, on a separate verified channel. The fingerprint lives in the tooltip on the lock icon and in Settings → Encryption. You verify once per contact, per key, and you are done. ## Whisper messages — private threads inside group chats It is now possible to reply privately to a single occupant of a room without leaving the room. These *whisper* messages follow [XEP-0045 §7.5](https://xmpp.org/extensions/xep-0045.html?ref=process-one.net) and appear in a distinct private thread so it is always clear they are not visible to the room at large. ![](https://www.process-one.net/content/images/2026/06/27-whisper-dark.png) ## Other improvements worth knowing **Compose while offline.** Messages typed before a connection is established are queued locally and sent as soon as the session comes online. **Connection status banner.** A banner now appears while the app is reconnecting, so you always know when you are temporarily offline rather than wondering whether a message failed to send. **Render-performance pass.** This release eliminates a class of re-render storms that affected the conversation list, command palette, room config modals, occupant panel, roster, search, and individual message rows during background sync and group-chat presence churn. The result is a noticeably smoother experience on busy accounts. **XMPP Console cleanup.** Stream Management packets are now hidden by default in the developer XMPP console. The toggle remains available for when you need to trace them. ## What comes next for encryption The encryption engine is a **plugin layer** sitting between the XMPP client and the UI. OpenPGP is the first plugin loaded into that framework. Adding a second protocol means writing a new plugin that implements the same interface: key management, encrypt, decrypt, trust state. The rest of the app — message routing, UI indicators, backup flow — does not need to change. This matters because no single protocol wins every use case. OpenPGP's shared-key model is ideal for multi-device history access; ratchet-based protocols like OMEMO excel at forward secrecy on single-device deployments; MLS is designed for large groups where pairwise key agreement would be impractical. The plan is to support several, letting users and deployments choose. The framework is in place; the question is which protocol to add second. **OMEMO** ([XEP-0384](https://xmpp.org/extensions/xep-0384.html?ref=process-one.net)) is the most widely deployed XMPP encryption protocol today. Adding it would maximise interoperability with existing XMPP clients. **MLS** ([RFC 9420](https://www.rfc-editor.org/rfc/rfc9420?ref=process-one.net)) is the newer IETF standard, designed from the ground up for multi-device and group scenarios, and is where the industry is heading long term. We have not decided yet. If you have a strong opinion, whether you are running an ejabberd deployment or just a user who cares, we would genuinely like to hear it. Just comment under that blog post. ## Release notes and download Full changelog on [GitHub](https://github.com/processone/fluux-messenger/releases/tag/v0.16.0?ref=process-one.net). Desktop builds for macOS, Windows, and Linux — plus the web version — are available on the [ProcessOne website](https://www.process-one.net/fluux/). ### Fluux Messenger 0.15.2: RTL Support, Faster Reconnection, and a Pile of Reliability Fixes URL: https://www.process-one.net/blog/fluux-messenger-0-15-2-rtl-support-faster-reconnection-and-a-pile-of-reliability-fixes/ Last updated: 2026-04-22T11:58:45.000Z This is a maintenance release with a few notable additions: RTL language support, faster reconnection after stream-management resume, and a handful of reliability fixes scattered across reconnect edge cases. ## RTL layout support (Arabic and Hebrew) and User interface tweaks Fluux Messenger now renders correctly in right-to-left languages. Arabic and Hebrew translations are included in this release. Both are beta quality, so if you spot translation errors or layout glitches, please open an issue. Getting community feedback early is the fastest way to improve coverage. On the UI side, blockquotes now use decorative quotation marks, a small polish detail that also helps in RTL contexts where quote direction matters. ![](https://www.process-one.net/content/images/2026/04/blog-blockquote-2.png) ## Reconnection: faster and far more reliable A significant chunk of this release is dedicated to making reconnects work the way they should. If you've seen Fluux Messenger freeze after waking your laptop, or loop on reconnect attempts, most of those scenarios are addressed here. **Faster resume:** When stream management successfully resumes a session, the client now skips redundant MAM queries. If the stream was cleanly resumed, there's no need to re-fetch history, so reconnection feels almost instant in good network conditions. **Sleep/wake handling:** Two separate bugs could cause the app to stall after a system sleep. One was a Tauri-specific reconnect stall, now recovered via native keepalive with a proxy fallback. The other was a post-wake auto-connect stall that happened after SASL negotiation completed but before the session was fully established. Both are fixed. **Loop prevention:** The reconnect attempt counter was incorrectly capped at the backoff ceiling, meaning it would stop growing and could trigger premature reconnect loops. That's fixed, and superseded connection attempts now get a dedicated error class so they're handled cleanly rather than causing UI freezes. **MUC room state:** Room state is now properly preserved across stream-management resume and interrupted fresh sessions. Previously, a reconnect could wipe stored room messages or fail to restore saved rooms, leaving history empty after resume. Both are fixed: live room messages are written directly to IndexedDB, and rooms are restored through the connect call so history loads correctly after SM resume. ## SASL2 and FAST token improvements Several fixes land around SASL2 and FAST token handling: - The websocket stream `from` attribute is now correctly set, which is required for SASL2 to be accepted on compliant servers. - FAST token rotation now works correctly across page-reload reconnects. - Token authentication is retried when the server field was initially empty on login. - A spurious "FAST token deleted" log message that appeared on first login (when no token existed yet) is suppressed. - The SASL2 user-agent identifier is updated, and server-side FAST token invalidation is triggered on logout. - The outbound stream-management state is now hydrated on resume, preventing an `ackQueue` crash that could occur in certain reconnect scenarios. ## Performance: per-conversation subscriptions Typing indicators and draft state now use per-conversation subscriptions rather than a single global subscription. This reduces re-renders in the conversation list during background sync, which was noticeable when many conversations were active simultaneously. The list stays responsive while the client is catching up on missed messages. ## Other fixes worth noting - **Notifications:** On web, notifications now use `ServiceWorker.showNotification()` for reliable delivery, replacing the previous approach that could silently fail. - **Image lightbox:** The lightbox no longer upscales images past their natural resolution, displaying the full-resolution original at actual size. - **Web image cache:** If the cache fetch fails, the client now falls back to loading directly from the URL instead of showing nothing. - **Upload errors:** HTTP upload errors are now displayed in the UI rather than failing silently. HTTP upload URLs are also now allowed. - **Dynamic import failures:** On failure, the client probes the runtime before reloading, and auto-reloads if the probe succeeds, skipping unnecessary hard reloads. - **Discovery calls:** Service discovery calls now run before the serial session-setup chain, which can shave time off the initial connection in some server configurations. - **Accessibility:** The scroll-to-bottom FAB now uses `inert` instead of `aria-hidden`, and the message toolbar "more" menu button vertical alignment is fixed. ## Getting 0.15.2 The [latest release](https://www.process-one.net/download/fluux-messenger/) is available on our website. The full changelog is in [CHANGELOG.md](https://github.com/processone/fluux-messenger/blob/main/CHANGELOG.md?ref=process-one.net) on Github. If you run into issues, especially around the new RTL translations or any of the reconnect scenarios, please open an issue. This release fixes a lot of edge cases and we want to make sure nothing slipped through. ### ejabberd 26.04 URL: https://www.process-one.net/blog/ejabberd-26-04/ Last updated: 2026-04-20T14:42:42.000Z **Contents:** - **[New limits options for XML parser](#parser)** - **[ChangeLog](#changelog)** - **[Acknowledgments](#ack)** - **[ejabberd 26.04 download & feedback](#download)** ## New limits options for XML parser This release adds new options that limit max memory used by XML parser used to process XMPP payloads, to prevent potential Denial of Service attack. The default values for pre-auth provide sufficient protection for ejabberd against non-authenticated users on c2s and s2s, so there is no need to change your configuration. The option `max_stanza_elements` sets a limit on the maximum number of XML elements that an individual stanza can contain. By default, this option is set to `infinity`. The pair of options `pre_auth_max_stanza_elements` and `pre_auth_max_stanza_size` define separate limits for sessions that haven't authenticated yet. The session will switch to the limits defined by the options `max_stanza_elements` and `max_stanza_size` after the client has successfully authenticated. The default values for these options are: 32 for `pre_auth_max_stanza_elements` and 8192 for `pre_auth_max_stanza_size`. All those options are recognized inside listener sections, and can be applied to `ejabberd_c2s` and `ejabberd_s2s_in` listeners. ## ChangeLog #### Core - Add new listener options to limit xml parser accepted input - Improve `leave_cluster` command to work even in own node - New predefined keyword `DATABASE_PATH` that points to the Mnesia spool dir - Support HOST keyword in `sql_database` toplevel option, set nice default value - Provide more details in log messages when using SQLite - Update documentation of jwt\_key to match the Docs site - ejabberd\_config: New default\_ram\_db/3 clause that checks module support - ejabberd\_sm: Remove session\_counter, used for get\_vh\_session\_number now removed #### Modules - `mod_http_fileserver`: Use integer in `ejabberd_hooks:add` as expected by "make hooks" - `mod_invites`: Add `--enable-bootstrap=no` to configure options to bypass download ([#4558](https://github.com/processone/ejabberd/pull/4558?ref=process-one.net)) - `mod_invites`: don't crash in `get_invite_by_invitee_t` for sql backend ([#4566](https://github.com/processone/ejabberd/pull/4566?ref=process-one.net)) - `mod_invites`: quick howto for creating integrity check checksums - `mod_invites`: remove dependency on jquery - `mod_mqtt`: Define RAM callbacks as optional - `mod_mqtt`: Use `default_ram_db` only if it really supports RAM storage - `mod_roster`: Fix bug introduced in 26.03 in commit d5c1440 ([#4564](https://github.com/processone/ejabberd/issues/4564?ref=process-one.net)) - `mod_roster_sql`: Cast `approved` integer as boolean when exporting Mnesia to SQL - `mod_shared_roster_sql`: Fix typo introduced 10 years ago in commit 0ea0ba30 #### Container and Installers - Bump Erlang/OTP 28.4.2 - make-binaries: Bump OpenSSL to 3.5.6 ### Full Changelog [https://github.com/processone/ejabberd/compare/26.03...26.04](https://github.com/processone/ejabberd/compare/26.02...26.03?ref=process-one.net) ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for the improvements in `mod_invites` And also to all the people contributing in the ejabberd chatroom, issue tracker... ## ejabberd 26.04 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/download/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying-process-one-downloads-integrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Fluux Messenger 0.15: Search, Themes, Polls, and a Whole Lot More URL: https://www.process-one.net/blog/fluux-messenger-0-15/ Last updated: 2026-04-07T08:44:32.000Z We have shipped Fluux Messenger 0.15, and it is packed with major advancements. After the excitement of the FOSDEM launch, the team put their heads down on three things users were asking for most: the ability to find past messages, a messenger that looks and feels different from Discord, and richer collaboration tools for group rooms. # Find anything, instantly Full-text search is now built into Fluux Messenger, every conversation, every room, searchable, locally and instantly. The search engine runs entirely on your device using an IndexedDB inverted index with prefix matching and highlighted result snippets. No messages leave your machine to power this. For rooms with deep history on the server, results are supplemented with MAM (Message Archive Management) server-side queries, giving you the best of both worlds: speed from local cache, completeness from the archive. A find-in-page mode (Cmd+F) lets you scan within any conversation, mirroring the browser experience developers expect. ![](https://www.process-one.net/content/images/2026/04/09-search-dark.png) ## Make it yours: a full theme system Fluux Messenger now ships with a proper design token system, three-tier (Foundation → Semantic → Component), and a theme picker bundled in the Appearance settings. Twelve themes are available out of the box: Fluux, Dracula, Nord, Gruvbox, Catppuccin Mocha, Solarized, One Dark, Tokyo Night, Monokai, Rosé Pine, Kanagawa, and GitHub. If none of them are quite right, you can import your own theme or inject CSS snippets directly. A global accent color picker with theme-specific presets lets you go further without writing a single line of code. Font size adjustment is now in Appearance settings as well. ![](https://www.process-one.net/content/images/2026/04/08-settings-dark.png) ## Polls in group rooms Reaction-based polls are now a first-class feature in MUC rooms. Create a poll with custom emojis, set a deadline, and let participants vote. The room enforces voting rules server-side, so results are trustworthy. Polls can be closed and reopened, and an "unanswered" banner nudges participants who haven't voted yet. Results are visualized inline and captured in the activity log. ![](https://www.process-one.net/content/images/2026/04/05-poll-dark.png) ## Faster connections with FAST authentication Fluux Messenger now supports **XEP-0484: FAST** (Fast Authentication Streamlining Tokens) alongside SASL2\. Reconnection after a network interruption or wake from sleep is now possible in the web version. ## Media cache Downloaded images are now cached to the filesystem, so they load instantly on revisit and don't count against your bandwidth twice. A new storage management screen in settings lets you see and clear the cache. ## Polish and fixes worth noting - **Emoji picker** (emoji-mart) with dynamic viewport positioning, so it never clips off-screen - **Last Activity (XEP-0012)** — offline contacts now show how long ago they were last seen - **Syntax highlighting** for code blocks, lazily loaded per language, with theme integration and a fullscreen modal for long snippets - **IRC-style mention detection** with consistent per-user colors (XEP-0392) - **VCard popovers** on occupant and member list nicks - **Scroll-to-bottom button** now shows an unread badge and implements two-step scroll: first click jumps to the new message marker, second click goes to the very bottom - **Particle burst animation** when adding a reaction, and a message send slide-up animation - Upgraded to **React 19** with the React Compiler for automatic memoization, and **Vite 8** with lazy-loaded views for a faster startup ## A note on Windows signing Starting with 0.15, the Windows binary is no longer signed. This is a temporary decision while we work through the signing infrastructure — full details are in [issue #290](https://github.com/processone/fluux-messenger/issues/290?ref=process-one.net). On install, Windows will prompt you to manually trust the application. We know this isn't ideal and are working to restore signed builds. --- ## Get it Fluux Messenger 0.15 is available now. [Download it here](https://www.process-one.net/download/fluux-messenger/) or check the [full changelog on GitHub](https://github.com/processone/fluux-messenger/blob/main/CHANGELOG.md?ref=process-one.net) for every detail. As always, feedback and bug reports are welcome. The community is the best part of building open-standard messaging software. ### ejabberd 26.03 URL: https://www.process-one.net/blog/ejabberd-26-03/ Last updated: 2026-04-13T14:00:36.000Z If you are upgrading from a previous version, there is a change in the SQL schemas, please read below. There are no changes in configuration, API commands or hooks. **Contents:** - **[Changes in SQL schemas](#sql)** - **[SASL channel binding changes](#sasl)** - **[ChangeLog](#changelog)** - **[Acknowledgments](#ack)** - **[Improvements in ejabberd Business Edition](#ebe)** - **[ejabberd 26.03 download & feedback](#download)** ## Changes in SQL schema This release adds a new column to the `rosterusers` table in the SQL database schemas to support roster pre-approval. This task is performed automatically by ejabberd by default. However, if your configuration file has disabled [update\_sql\_schema](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#update%5Fsql%5Fschema) toplevel option, you must perform the SQL schema update manually yourself. Those instructions are valid for MySQL, PostgreSQL and SQLite, both default and new schemas: ```sql ALTER TABLE rosterusers ADD COLUMN approved boolean NOT NULL DEFAULT false; ALTER TABLE rosterusers ALTER COLUMN approved DROP DEFAULT; ``` You can ignore the second query on SQLite. ## SASL channel binding changes This version adds the ability to configure the handling of the client flag *'wanted to use channel-bindings but was not offered one'*. By default, ejabberd aborts connections that present this flag, as this could indicate the presence of a rogue MITM proxy between the server and the client that strips the exchanged data of information required for this. This can cause problems for servers that use a proxy server which terminates the TLS connection (i.e. there is a MITM proxy, but it is approved by the server administrator). To handle this situation, we have added code to ignore this flag if the server administrator disables channel binding handling by disabling the `-PLUS` authentication mechanisms in the configuration file: ```yaml disable_sasl_mechanisms: - SCRAM-SHA-1-PLUS - SCRAM-SHA-256-PLUS - SCRAM-SHA-512-PLUS ``` We also ignore this flag for SASL2 connections if offered authentication methods filtered by available user passwords did disable all `-PLUS` mechanisms. ## ChangeLog #### Core - Fix MySQL authentication for TLS connections that required auth plugin switch - Improve handling of scram *'wanted to use channel-bindings but was not offered one'* flag - Add ability for mod\_options values to depend on other options - Don't fail to classify stand-alone chat states - Fix some warnings compiling with Erlang/OTP 29 ([#4527](https://github.com/processone/ejabberd/issues/4527?ref=process-one.net)) - `ejabberd_ctl`: Document how to set empty lists in ejabberdctl and WebAdmin - `ejabberd_http`: Add handling of `Etag` and `If-Modified-Since` headers to files served by `mod_http_upload` - `ejabberd_http`: Ignore whitespaces at end of host header - SQL: Add ability to mark that column can be null in e\_sql\_schema - Tests: Add tests for SASL2 - Tests: Make table cleanup in test more robust #### Modules - `mod_fast_auth`: Offered methods are based on available channel bindings - `mod_http_api`: Always hide password in log entries - `mod_mam`: Call `store_mam_message` hook for messages that `user_mucsub_from_muc_archive` was filtering out - `mod_mam_sql`: Only provide the new XEP-0431 `fulltext` field, not old custom `withtext` - `mod_muc_room`: Fix duplicate stanza-id in muc mam responses generated from local history ([#4544](https://github.com/processone/ejabberd/issues/4544?ref=process-one.net)) - `mod_muc_room`: Fix hook name in commit 7732984 ([#4526](https://github.com/processone/ejabberd/issues/4526?ref=process-one.net)) - `mod_pubsub_serverinfo`: Don't use `gen_server:call` for resolving pubsub host - `mod_roster`: Add support for roster pre-approval ([#4512](https://github.com/processone/ejabberd/issues/4512?ref=process-one.net)) - `mod_roster`: Fix display of groups in WebAdmin when it's a list - `mod_roster`: in WebAdmin page, first execute SET actions, later GET - `mod_roster_mnesia`: Improve transformation code #### mod\_invites - Makefile: Run invites-deps only when files are missing - Fix path to bootstrap files - Check at start time the syntax of landing\_page option ([#4525](https://github.com/processone/ejabberd/issues/4525?ref=process-one.net)) - Send 'Link' http header ([#4531](https://github.com/processone/ejabberd/issues/4531?ref=process-one.net)) - Set meta.pre-auth to skip redirect\_url if token validated ([#4535](https://github.com/processone/ejabberd/issues/4535?ref=process-one.net)) - Many security fixes ([#4539](https://github.com/processone/ejabberd/issues/4539?ref=process-one.net)) - Add favicon and change color to match ejabberd branding - Enable dark mode - Add support for webchat\_url - Migrate to bootstrap5 and update jquery - No inline scripts - Make format csrf token - Add csrf token to failed post - Include js/css deps in static dir - Correct hashes for bootstrap 4.6.2 - Hint at type for landing\_page opt - Many more security fixes ([#4538](https://github.com/processone/ejabberd/issues/4538?ref=process-one.net)) - Check CSRF token in register form - Add integrity hashes to scripts and css - Comment unused resources - Add security headers - Remove debug log of whole query parameters (including pw) - Don't crash on unknown host from http host header - Make creating invite transactional - Set overuse limits ([#4540](https://github.com/processone/ejabberd/issues/4540?ref=process-one.net)) - Fix broken path when behind proxy with prefix ([#4547](https://github.com/processone/ejabberd/issues/4547?ref=process-one.net)) #### Container and Installers - Bump Erlang/OTP 28.4.1 - make-binaries: Bump libexpat to 2.7.5 - make-binaries: Bump zlib to 1.3.2 - make-binaries: Enable missing crypto features ([#4542](https://github.com/processone/ejabberd/issues/4542?ref=process-one.net)) #### Translations - Update Bulgarian translation - Update Catalan and Spanish translations - Update Chinese Simplified translation - Update Czech translation - Update French translation - Update German translation ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for the roster pre-approval feature, [sponsored by NLnet](https://nlnet.nl/project/ejabberd-invites/?ref=process-one.net) - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for the improvements in `mod_invites` - [Holger Weiß](https://github.com/weiss?ref=process-one.net) for improvements in binary installers - [Mr. EddX](https://github.com/MrEddX?ref=process-one.net) for updating the Bulgarian translation - [Sketch6580](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net) for updating the Chinese (Simplified) translation - [ffunk](https://github.com/hollymrklm?ref=process-one.net) for updating the Czech translation - [Dyxux](https://github.com/dyxux?ref=process-one.net) for updating the French translation - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for updating the German translation And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get the following changes: - Add p1db backend for [mod\_auth\_fast](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fauth%5Ffast) - Fix issue when cleaning MAM messages stored in p1db - `mod_unread` fixes - Web push fixes ### Full Changelog [https://github.com/processone/ejabberd/compare/26.02...26.03](https://github.com/processone/ejabberd/compare/26.02...26.03?ref=process-one.net) ## ejabberd 26.03 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/download/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying-process-one-downloads-integrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Fluux Messenger 0.14.0 - Full Room Control & Richer Contact Profiles URL: https://www.process-one.net/blog/fluux-messenger-0-14-0/ Last updated: 2026-03-20T11:15:55.000Z Fluux Messenger 0.14.0 is a major release. Fluux Messenger is growing fast. Thank you to everyone contributing, testing, and spreading the word! This release finally brings room management. Moderators can retract messages, owners can manage rooms end-to-end, contacts have real profiles now, and the fix list is longer than usual. A lot landed in this release. ## What's New ### Full MUC Room Management Fluux Messenger now supports the complete room lifecycle directly from the client. You can **create, configure, and destroy MUC rooms** without reaching for an admin console. Room owners also get full user management tools: change affiliations and roles, kick or ban occupants, and browse room directories with proper RSM pagination. A new modal lets you join any room directly by entering its JID. This makes Fluux Messenger a serious option for teams self-hosting their own ejabberd server and managing communities day-to-day. ![](https://www.process-one.net/content/images/2026/03/Fluux-Messenger---Team-Chat-1.png) ### Message Moderation (XEP-0425) Moderators can now **retract messages** posted by other users in MUC rooms, with full attribution and reason display. This is a meaningful step toward responsible community management inside open, sovereign messaging infrastructure — no proprietary platform required. ### MUC Hat Management (XEP-0317) Room owners can now **define, assign, and remove hats** for occupants via ad-hoc commands. Hats are a lightweight, expressive way to convey roles and status in a room beyond the standard affiliation model. The full hat management UI is accessible directly from the room interface. ### Rich Contact Profiles with vCard (XEP-0054) Contact information just got a lot more useful. Fluux Messenger now **displays vCard data** — full name, organisation, email, and country — in contact popovers and profile views. You can also **edit your own vCard** directly from profile settings, adding, updating, or removing fields as needed. No more opaque JIDs; your contacts now have a face and a name. ### Per-Room Ignored Users (XEP-0223) You can now **ignore specific users on a per-room basis**, with ignore lists stored server-side via Personal Eventing Protocol (XEP-0223). Filtering has been improved to cross-match JIDs and occupant IDs, and notifications from ignored users (including quoted replies) are now properly suppressed. ### Contact Management from the Room A new **contact management dropdown in the occupant sidebar** and a dedicated **contact addition button in the profile screen** make it easy to manage your contact list without leaving the conversation. Right-clicking (or long-pressing) a nickname in room messages now brings up an occupant context menu with quick actions. ### Quality of Life - **Entity Time (XEP-0202)** — see your contact's local time in the chat header and contact popover, handy for distributed teams. - **Message delivery errors** are now displayed inline, with the option to **retry sending** directly. - **Do Not Disturb mode** now suppresses sound and desktop notifications automatically. - **Font size setting** added to appearance preferences. - **Avatar lightbox** — click an avatar in message view to see it full-size. - **PEP-based conversation list sync** (ConversationSync module) keeps your sidebar consistent across sessions. - **External links** now open in a Tauri webview popup instead of jumping to the system browser. - **Full-screen occupant panel** on small screens for a better mobile experience. ## Bug Fixes & Reliability This release addresses a significant number of issues: - Active rooms now correctly move to the top of the sidebar on new messages - Missing room messages after reconnect or app restart - Blank window in MUC rooms caused by a stale ResizeObserver - Reactions UI properly enabled in rooms with stable occupant identity - Native window theme now syncs correctly with system mode in Tauri - Modals no longer close when click-dragging from inside to outside - Fixed: owner showing as moderator in the chat view - Navigation stack management improved for mobile --- ## Get Fluux Messenger Download for [Windows](https://github.com/processone/fluux-messenger/releases?ref=process-one.net), [macOS](https://github.com/processone/fluux-messenger/releases?ref=process-one.net), or [Linux](https://github.com/processone/fluux-messenger/releases?ref=process-one.net) on the latest Release page. **Source code is available at**: [GitHub](https://github.com/processone/fluux-messenger?ref=process-one.net) --- > Your messages, your infrastructure: no vendor lock-in. > Sovereign by design. Built in Europe, for everyone. ### Fluux Messenger 0.13.0 - Native TCP Connection & Complete EU Language Coverage URL: https://www.process-one.net/blog/fluux-messenger-0-13/ Last updated: 2026-02-12T17:39:23.000Z We're excited to announce Fluux Messenger 0.13.0, featuring native TCP connections, complete European language coverage, and significant performance improvements. Also, we recently passed the first 100 stars on GitHub. Thank you for your support and for believing in open, sovereign messaging ! [![Star History Chart](https://api.star-history.com/svg?repos=processone/fluux-messenger&type=date&legend=bottom-right)](https://www.star-history.com/?ref=process-one.net#processone/fluux-messenger&type=date&legend=bottom-right) ## What's New ### Native TCP Connection Support on Desktop Desktop users can now connect directly to XMPP servers via native TCP through our WebSocket proxy implementation. This means lower latency, better reliability, and native protocol handling. No more browser limitations. **We believe that's a nice milestone worth a blog post**. Until now, desktop users needed their XMPP server to support WebSocket connections. With v0.13.0, you can connect to any standard XMPP server. We estimate this will enable **80% of users who couldn't connect before** to finally use Fluux Messenger with their existing servers. ### Complete European Union Language Coverage Fluux Messenger now supports all 26 EU languages, making it truly pan-European. From Bulgarian to Swedish, Croatian to Maltese, we've got you covered. Languages include: - Bulgarian, Croatian, Czech, Danish, Dutch, English, Estonian, Finnish, French, German, Greek, Hungarian, Icelandic, Irish, Italian, Latvian, Lithuanian, Maltese, Norwegian, Polish, Portuguese, Romanian, Slovak, Slovenian, Spanish, Swedish. Dynamic locale loading means faster initial startup while maintaining comprehensive language support. If you spot any translation issues, feel free to contribute on our [GitHub repository](https://github.com/processone/fluux-messenger?ref=process-one.net). ### Clipboard Image Paste Paste images directly from your clipboard with `Cmd+V` (macOS) or `Ctrl+V` (Windows/Linux). Copy from anywhere, paste into Fluux. It (should) just work ;). Tested and confirmed with Safari's "Copy Image" feature and system clipboard operations so far. ### Clear Local Data on Logout New privacy option to completely clear local data when logging out. Perfect for shared devices or when you need a fresh start. ## Performance & Reliability Improvements - **Smarter Message History Loading** \- We've completely redesigned our Message Archive Management (MAM) strategy. Message history now loads intelligently based on your scrolling behavior and available data, reducing unnecessary server requests. - **Better Resource Management** \- Fixed duplicate avatar fetches when hashes haven't changed, reducing bandwidth usage and improving profile picture loading times. - **Rock-Solid Scroll Behavior** \- Media loading no longer disrupts your scroll position. The scroll-to-bottom feature now works reliably, even when images and files are loading. - **Better Windows Tray** \- Improved tray behavior on Windows for a more native experience. **macOS Sleep Recovery** \- Fixed layout corruption that could occur after your Mac woke from sleep. ## UI & UX Polish - **Consistent attachment styling** across light and dark themes - **Fixed sidebar switching** with `Cmd+U` keyboard shortcut - **Improved new message markers** \- position correctly maintained when switching conversations - **Better context menus** \- always stay within viewport bounds, no more cut-off menus - **Markdown preview accuracy** \- bold and strikethrough now properly shown in message previews ## Linux Packaging Improved Linux packaging using native distribution tools for better integration with your system package manager. ## Developer Experience Centralized notification state with viewport observer provides better performance and more reliable notification handling across the application. --- ## Get Fluux Messenger Download for [Windows](https://github.com/processone/fluux-messenger/releases?ref=process-one.net), [macOS](https://github.com/processone/fluux-messenger/releases?ref=process-one.net), or [Linux](https://github.com/processone/fluux-messenger/releases?ref=process-one.net) in the latest Release page. **Source code is available at**: [GitHub](https://github.com/processone/fluux-messenger?ref=process-one.net) --- > Your messages, your infrastructure : no vendor lock-in. > Sovereign by design. Built in Europe, for everyone. ### 🚀 ejabberd 26.02 URL: https://www.process-one.net/blog/ejabberd-26-02/ Last updated: 2026-02-11T10:01:06.000Z **Contents:** - **[ChangeLog](#changelog)** - **[Acknowledgments](#ack)** - **[Improvements in ejabberd Business Edition](#ebe)** - **[ejabberd 26.02 download & feedback](#download)** ## ChangeLog - Fixes issue with adding hats data in presences send by group chats ([#4516](https://github.com/processone/ejabberd/issues/4516?ref=process-one.net)) - Removes `mod_muc_occupantid` modules, and integrates its functionality directly into `mod_muc` ([#4521](https://github.com/processone/ejabberd/issues/4521?ref=process-one.net)) - Fixes issue with reset occupant-id values after restart of ejabberd ([#4521](https://github.com/processone/ejabberd/issues/4521?ref=process-one.net)) - Improves handling of mediated group chat invitations in `mod_block_stranger` ([#4523](https://github.com/processone/ejabberd/issues/4523?ref=process-one.net)) - Properly install `mod_invites` templates in `make install` call ([#4514](https://github.com/processone/ejabberd/issues/4514?ref=process-one.net)) - Better errors in `mod_invites` ([#4515](https://github.com/processone/ejabberd/issues/4515?ref=process-one.net)) - Accessibility improvements in `mod_invites` ([#4524](https://github.com/processone/ejabberd/issues/4524?ref=process-one.net)) - Improves handling of request with invalid url encoded values in request handled by `ejabberd_http` - Improves handling of invalid responses to disco queries in `mod_pubsub_serverinfo` - Fixes conversion of MUC room configs from ejabberd older than 21.12 - Fixes to autologin in WebAdmin If you are upgrading from a previous version, there are no changes in SQL schemas, configuration, API commands or hooks. Notice that [mod\_muc](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmuc) now incorporates the feature from [mod\_muc\_occupantid](https://docs.ejabberd.im/archive/26.01/modules/?ref=process-one.net#mod%5Fmuc%5Foccupantid), and that module has been removed. You can remove `mod_muc_occupantid` in your configuration file as it is unnecessary now, and ejabberd simply ignores it. Check also the commit log: [https://github.com/processone/ejabberd/compare/26.01...26.02](https://github.com/processone/ejabberd/compare/26.01...26.02?ref=process-one.net) ## Acknowledgments We would like to thank the contributions to the source code and translations provided by: - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for the improvements in `mod_invites` - [Mr. EddX](https://github.com/MrEddX?ref=process-one.net) for updating the Bulgarian translation - [Sketch6580](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net) for updating the Chinese (Simplified) translation - [ffunk](https://github.com/hollymrklm?ref=process-one.net) for updating the Czech translation - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for updating the German translation And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get the following change: - Change `default_ram_db` from `mnesia` to `p1db` when using `p1db` `cluster_backend` ## ejabberd 26.02 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/download/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying-process-one-downloads-integrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Introducing Fluux Messenger: A Modern XMPP Client Born from a Holiday Coding Session URL: https://www.process-one.net/blog/introducing-fluux-messenger-a-modern-xmpp-client-born-from-a-holiday-coding-session/ Last updated: 2026-01-28T17:51:55.000Z It was mid-December 2025, just before the Christmas break. My favorite XMPP client had broken on the main branch I was using. Frustrated, rather than waiting for a fix, I decided I wanted to give another try at working on a client. This time, I would be using the opportunity to explore a new set of tools I was curious about: TypeScript, React, and Tauri. What started as a weekend experiment quickly turned into something more. Using AI tools to accelerate the initial setup, I found myself totally absorbed in the work. Days blurred together as features took shape. By early January, what had been a personal scratch project had become a surprisingly capable desktop client. When I demonstrated it to my coworkers at ProcessOne, their reaction was unanimous: this was worth pursuing seriously. We decided to put the entire company behind the effort. Today, we're sharing the first public release of **Fluux Messenger**. ## More Than Just Another Chat Client At ProcessOne, we've spent over two decades building messaging infrastructure. Our XMPP server, ejabberd, has powered some of the world's largest messaging deployments. But we've always approached messaging from the server side. Fluux Messenger represents something new for us, bringing that same engineering philosophy to the client. The key innovation isn't in the UI (though we're proud of it). It's in what lies beneath: the **Fluux SDK**. ## The Fluux SDK: Bridging Two Worlds Anyone who has built an XMPP client knows the challenge. XMPP is event-driven, signal-based, asynchronous. Modern UI frameworks expect reactive state, typed data, and predictable updates. There's an impedance mismatch between these two worlds. The Fluux SDK is our answer. It provides a high-level TypeScript API that handles all XMPP complexity internally. Developers work with clean types and reactive state, not XML stanzas. The SDK maintains local cache, manages reconnection, and handles synchronization intelligently. It's not a passive pipe between server and UI; it's an active participant that makes the client easier to develop and more resilient. As an example, the client is not telling the SDK which presence it wants to publish when stepping away from the computer, but it will signal to the SDK that it is inactive. The SDK is responsible for doing the right thing. This three-tiered architecture, Server -> Headless client (SDK) -> UI, lets us apply the same design principles that made ejabberd scalable to the client side. Distributed logic, local-first responsiveness, server-side efficiency. ## What Fluux Messenger Offers Today The current release (v0.11.1) already includes substantial functionality: - **Reliable connection** and message management - **Cross-platform desktop app** for Windows, macOS, and Linux, built on Tauri for a lightweight native experience - **Web version**: It works great on the Web as well. - **40+ XMPP extensions (XEPs)** implemented, including message archive management, multi-user chat, HTTP file upload, message carbons, and reactions - **MUC support** with @mentions notification and bookmarks - **Local message cache storage** using IndexedDB with automatic sync on reconnect - **Built-in XMPP console** for developers and power users who want to see what's happening under the hood - **Preliminary admin capabilities** letting you manage your ejabberd server directly from the client (But this is still mostly a work in progress). - **8 languages** supported out of the box - **Light and dark modes** with theme system to come ![](https://www.process-one.net/content/images/2026/01/Fluux-Messenger-0.11.1-1.png) What I envision for **Fluux Messenger** is to follow the steps of major projects like **Obsidian** or **VSCode**. In my wildest dreams, I expect **Fluux Messenger** to become as configurable and versatile as those tools. ## The Road Ahead This is an ambitious project. The roadmap stretches far into the future, and we're just getting started. Our plans include mobile support through PWA and eventually native apps, expansion to other frameworks (Vue, Svelte), and Kotlin Multiplatform for Android and iOS. But ambitious doesn't mean closed. Fluux Messenger is open source under AGPL-3.0\. We believe that modern, privacy-respecting messaging shouldn't require vendor lock-in. Connect to any XMPP server. Host it yourself. I used AI to bootstrap this project and accelerate my learning phase. Many developers do now. But we are crafters at ProcessOne, and we want to own the responsibility for great code. Those who know me will tell you I'll be relentless until I master React and TypeScript, and they know I will. Fast. ## A Continuation of ejabberd's Vision Fluux Messenger represents the client-side continuation of what we started with ejabberd over twenty years ago. The same principles, scalability, reliability, clean architecture, now flow from server to client. If you've trusted ejabberd to power your messaging infrastructure, we hope you'll trust Fluux Messenger to be the interface your users deserve. This is the beginning of an exciting journey. We hope you'll join us. --- ## Get started - Download from [GitHub Releases](https://github.com/processone/fluux-messenger/releases/latest?ref=process-one.net) - Join the conversation: fluux-messenger@conference.process-one.net - Report issues and suggest features on [GitHub](https://github.com/processone/fluux-messenger/issues?ref=process-one.net) If you share our vision for clean, reactive messaging APIs, we'd love to collaborate. Reach out and let's grow the Fluux community together. ### 🚀 ejabberd 26.01 URL: https://www.process-one.net/blog/ejabberd-26-01/ Last updated: 2026-01-21T17:50:12.000Z This release is the result of three months of development, implementing those new features, and fixing bugs. **Release Highlights:** - **[Database Serialization](#database)** - **[Roster Invites and Invite-based Account Registration](#invites)** If you are upgrading from a previous version, there are no mandatory changes in SQL schemas, configuration, API commands or hooks. However new `mod_invites` uses a new table in databases, see below. **Other contents:** - **[SQL table for mod\_invites](#sqlinvites)** - **[New replaced\_connection\_timeout](#replaced)** - **[Improved mod\_http\_fileserver docroot option](#docroot)** - **[Supported XEP Versions](#xep)** - **[Erlang, Elixir and Container](#erlang)** - **[Improved ERL\_DIST\_PORT](#erldistport)** - **[New make relivectl](#relivectl)** - **[WebAdmin Menu Links](#webadmin)** - **[Acknowledgments](#ack)** - **[Improvements in ejabberd Business Edition](#ebe)** - **[ChangeLog](#changelog)** - **[ejabberd 26.01 download & feedback](#download)** Below is a detailed breakdown of the improvements and enhancements: ## Database Serialization This feature adds new way for migrating data between [database backends](https://docs.ejabberd.im/admin/configuration/database/?ref=process-one.net) by exporting data from one backend to a file and importing that into different backend (or possibly to same backend but on different machine). Migrating data using this can be executed by first exporting all data with [export\_db](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#export%5Fdb) command, changing configuration of ejabberd and switching modules to use new database backend, and then importing previously exported data using [import\_db](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#import%5Fdb) command. This mechanism works by calling those new command from ejabberdctl, for exporting data: - `ejabberdctl export_db ` - `ejabberdctl export_db_abort ` - `ejabberdctl export_db_status ` and for importing: - `ejabberdctl import_db ` - `ejabberdctl import_db_abort ` - `ejabberdclt import_db_status ` Exporting and importing work in background after starting them from [ejabberdctl](https://docs.ejabberd.im/admin/guide/managing/?ref=process-one.net#ejabberdctl) (commands executed by ejabberdctl have time limit for how long they can work, with this setup there should be not issue with export or import getting aborted by that), and current progress of background operation can be tracked by calling corresponding `*_db_status` command. Operation in progress can be also aborted by executing `*_db_abort` command. ## Roster Invites and Invite-based Account Registration Until now the canonical method to register an account in ejabberd was to let anybody register accounts using In-Band Registration (IBR) ([mod\_register](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fregister)) or Web Registration ([mod\_register\_web](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fregister%5Fweb)), and then try to limit abuse with access limitations or [CAPTCHAs](https://docs.ejabberd.im/admin/configuration/basic/?ref=process-one.net#captcha). Often this process got abused, with the result that account registration had to be disabled and rely on manual registration by administrators. The new [mod\_invites](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Finvites) implements support for invite-based account registration: administrators can generate invitation URLs, and send them to the desired users (by email or whatever). Then the user that receives an invitation can visit this invitation URL to register a new account. On top of that, `mod_invites` lets you create Roster Invites: you can send a link to some other person so they can connect to you in a very user-friendly and intuitive way that doesn't require any further interaction. If account creation is allowed, these links will also allow to setup an account in case the recipient doesn't have one yet. Relevant links: - [mod\_invites documentation](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Finvites) - [Great Invitations](https://blog.prosody.im/great-invitations/?ref=process-one.net), the original Prosody blog post that described this feature - [XEP-0379: Pre-Authenticated Roster Subscription](https://xmpp.org/extensions/xep-0379.html?ref=process-one.net) - [XEP-0401: Ad-hoc Account Invitation Generation](https://xmpp.org/extensions/xep-0401.html?ref=process-one.net) - [XEP-0445: Pre-Authenticated In-Band Registration](https://xmpp.org/extensions/xep-0445.html?ref=process-one.net) - This development was [funded by NLnet](https://nlnet.nl/project/ejabberd-invites/?ref=process-one.net) Quick setup: 1. If using SQL storage for the modules and have disabled the [update\_sql\_schema](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#update%5Fsql%5Fschema) toplevel option, then [create manually the SQL table](#sqlinvites), see below. 2. If you plan to use the landing page included with `mod_invites`, install JavaScript libraries [jQuery](https://jquery.com/?ref=process-one.net) version [3.7.1](https://code.jquery.com/jquery-3.7.1.min.js?ref=process-one.net) and [Bootstrap](https://getbootstrap.com/?ref=process-one.net) version [4.6.2](https://github.com/twbs/bootstrap/releases/download/v4.6.2/bootstrap-4.6.2-dist.zip?ref=process-one.net). This example configuration will assume they are installed in `/usr/share/javascript`. The `ejabberd` container image already includes those libraries. Some quick examples, in case you need some help: - Debian and related: ```shell apt install libjs-jquery libjs-bootstrap4 ``` - AlpineLinux and other operating systems where you can install `npm`, for example: ```shell apk -U add --no-cache nodejs npm ca-certificates npm init -y \ && npm install --silent jquery@3.7.1 bootstrap@4.6.2 mkdir -p /usr/share/javascript/jquery mkdir -p /usr/share/javascript/bootstrap4/{css,js} cp node_modules/jquery/dist/jquery.min.js /usr/share/javascript/jquery/ cp node_modules/bootstrap/dist/css/bootstrap.min.css /usr/share/javascript/bootstrap4/css/ cp node_modules/bootstrap/dist/js/bootstrap.min.js /usr/share/javascript/bootstrap4/js/ ``` - Generic method using the included script: ```shell tools/dl_invites_page_deps.sh /usr/share/javascript ``` 3. Configure ejabberd to serve the JavaScript libraries in path `/share`; serve mod\_invites in any path of your selection; and enable mod\_invites with some basic options. Remember to setup mod\_register to allow registering accounts using mod\_invites. For example: ```yaml listen: - port: 5443 ip: "::" module: ejabberd_http tls: true request_handlers: /invites: mod_invites /share: mod_http_fileserver modules: mod_http_fileserver: docroot: /share: /usr/share/javascript mod_invites: access_create_account: configure landing_page: auto mod_register: allow_modules: - mod_invites ``` 4. There are many ways to generate invitations: - Login with an admin account, then you can execute Ad-Hoc Commands like "Invite User" and "Create Account" - If [mod\_adhoc\_api](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fadhoc%5Fapi) is enabled, you can execute equivalent API Commands [generate\_invite](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#generate%5Finvite) and [generate\_invite\_with\_username](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#generate%5Finvite%5Fwith%5Fusername) - Run those API Commands from the command-line, for example: `ejabberdctl generate_invite localhost` 5. All those methods give you an invitation URL that you can send it to the desired user, and looks like ``` https://localhost:5443/invites/Yrw5nuC1Kpxy9ymbRzmVGzWQ ``` 6. The destination user (or yourself) can visit that invitation URL and follow the instructions to register the account and download a compatible client. If the user has installed already a compatible XMPP client, you don't no need to install JavaScript libraries and setup a landing page. In that case, when generating an invitation you will get only the XMPP URI; when the user opens that URI in a web browser, it will automatically open the XMPP client and the corresponding registration window. Probably you don't want to expose the port directly, then you need to setup Nginx or Apache to act as a "reverse" proxy and change your `landing_page` parameter accordingly, for example just `https://@HOST@/invites/{{ invite.token }}` Notice that the landing page can be fully translated using the existing [ejabberd localization feature](https://docs.ejabberd.im/developer/extending-ejabberd/localization/?ref=process-one.net). ![](https://www.process-one.net/content/images/2026/01/ejabberd_blog_2601.png) ## [](sqlinvites)SQL table for mod\_invites There is a new table `invite_token` in SQL schemas, used by the new `mod_invites`. If you want to use this module, there are two methods to update the SQL schema of your existing database: If using MySQL or PosgreSQL, you can enable the option [update\_sql\_schema](../../admin/configuration/toplevel.md#update%5Fsql%5Fschema) and ejabberd will take care to update the SQL schema when needed: add in your ejabberd configuration file the line `update_sql_schema: true` Notice that support for MSSQL in `mod_invites` has not yet been implemented or tested. If you are using other database, or prefer to update manually the SQL schema: - MySQL singlehost schema: ```sql CREATE TABLE invite_token ( token text NOT NULL, username text NOT NULL, invitee text NOT NULL DEFAULT (''), created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, expires timestamp NOT NULL, type character(1) NOT NULL, account_name text NOT NULL, PRIMARY KEY (token(191)) ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE INDEX i_invite_token_username USING BTREE ON invite_token(username(191)); ``` - MySQL multihost schema: ```sql CREATE TABLE invite_token ( token text NOT NULL, username text NOT NULL, server_host varchar(191) NOT NULL, invitee text NOT NULL DEFAULT '', created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, expires timestamp NOT NULL, type character(1) NOT NULL, account_name text NOT NULL, PRIMARY KEY (token(191)), ) ENGINE=InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE INDEX i_invite_token_username USING BTREE ON invite_token(username(191)); ``` - PostgreSQL singlehost schema: ```sql CREATE TABLE invite_token ( token text NOT NULL, username text NOT NULL, invitee text NOT NULL DEFAULT '', created_at timestamp NOT NULL DEFAULT now(), expires timestamp NOT NULL, "type" character(1) NOT NULL, account_name text NOT NULL, PRIMARY KEY (token) ); CREATE INDEX i_invite_token_username ON invite_token USING btree (username); ``` - PostgreSQL multihost schema: ```sql CREATE TABLE invite_token ( token text NOT NULL, username text NOT NULL, server_host text NOT NULL, invitee text NOT NULL DEFAULT '', created_at timestamp NOT NULL DEFAULT now(), expires timestamp NOT NULL, "type" character(1) NOT NULL, account_name text NOT NULL, PRIMARY KEY (token) ); CREATE INDEX i_invite_token_username_server_host ON invite_token USING btree (username, server_host); ``` - SQLite singlehost schema: ```sql CREATE TABLE invite_token ( token text NOT NULL, username text NOT NULL, invitee text NOT NULL DEFAULT '', created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, expires timestamp NOT NULL, type character(1) NOT NULL, account_name text NOT NULL, PRIMARY KEY (token) ); CREATE INDEX i_invite_token_username ON invite_token(username); ``` - SQLite multihost schema: ```sql CREATE TABLE invite_token ( token text NOT NULL, username text NOT NULL, server_host text NOT NULL, invitee text NOT NULL DEFAULT '', created_at timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, expires timestamp NOT NULL, type character(1) NOT NULL, account_name text NOT NULL, PRIMARY KEY (token) ); CREATE INDEX i_invite_token_username_server_host ON invite_token(username, server_host); ``` ## [](replaced)New replaced\_connection\_timeout toplevel option The new [replaced\_connection\_timeout](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#replaced%5Fconnection%5Ftimeout) toplevel option enables new session to wait for termination of session that it replaces. This should mitigate problems where old session presences unavailable sometimes were delivered after new session sent it's presence available. ## Improved mod\_http\_fileserver docroot option [mod\_http\_fileserver](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fhttp%5Ffileserver) is a module to serve files from the local disk over HTTP, useful if you just want to serve some HTML or binary files that don't need PHP, and don't need to setup or configure a separate full-blown web server. Now the `docroot` option may be a map of paths to serve, allowing this module to serve several paths with different directories for different purposes. For example, let's serve some public content from `/var/service/www`, also shared JavaScript libraries, and for base URL let's serve from `/var/www`: ```yaml listen: - port: 5280 module: ejabberd_http request_handlers: /pub/content: mod_http_fileserver /share: mod_http_fileserver /: mod_http_fileserver modules: mod_http_fileserver: docroot: /pub/content: /var/service/www /share: /usr/share/javascript /: /var/www ``` Notice that ejabberd includes many modules that serve web services, that may be useful to save you from setting up a full-blown web server, see [ejabberd\_http](https://docs.ejabberd.im/admin/configuration/listen/?ref=process-one.net#ejabberd%5Fhttp). ## Supported XEP versions ejabberd supports close to 90 [XMPP extension protocols (XEPs)](https://xmpp.org/extensions/?ref=process-one.net), either directly implemented in ejabberd source code, in the [libraries](https://docs.ejabberd.im/developer/repositories/?ref=process-one.net#mandatory) that implement many of the internal features, or in other ejabberd modules available in other repositories like [ejabberd-contrib](https://docs.ejabberd.im/admin/guide/modules/?ref=process-one.net#ejabberd-contrib). Those XEPs are updated regularly to bring major improvements, minor changes, fixing typos, editorial or cosmetic changes... and this requires a regular review of those XEP updates in the software implementations to keep them up to date, or at least to document what exact version of the protocols are implemented. In this sense, we have reviewed all the XEP versions that ejabberd and erlang [xmpp](https://github.com/processone/xmpp/?ref=process-one.net) library were not up-to-date, and have identified which ones are already up-to-date in their DOAP files. Now the pages at XMPP.org describe more accurately the supported protocol versions, see [ejabberd at XMPP.org](https://xmpp.org/software/ejabberd/?ref=process-one.net) and [erlang-xmpp at XMPP.org](https://xmpp.org/software/erlang-elixir-xmpp/?ref=process-one.net). ## Erlang, Elixir and Container ejabberd can be compiled with [Erlang/OTP](https://www.erlang.org/?ref=process-one.net) from 25.0 up to the latest 28.3.1\. Regarding [Elixir](https://elixir-lang.org/?ref=process-one.net) support, ejabberd supports from Elixir 1.14.0 up to the latest 1.19.5 Right now ejabberd compiles correctly with Erlang/OTP from `git` development branch and Elixir 1.20.0-RC1, so hopefully compatibility with the upcoming Erlang/OTP 29 and Elixir 1.20 will be easily achievable. [Binary installers](https://docs.ejabberd.im/admin/install/binary-installer/?ref=process-one.net) and the `ejabberd` container now include Erlang/OTP 28.3.1 instead of 27.3, and Elixir 1.19.5 instead of 1.18.4. Speaking of the [container images](https://docs.ejabberd.im/CONTAINER/?ref=process-one.net), both `ejabberd` and `ecs` bring other minor changes: they expose more [ports](https://docs.ejabberd.im/admin/guide/security/?ref=process-one.net#firewall-settings): 5478 UDP (STUN service), 7777 (SOCKS5 file transfer proxy) and 50000-50099 UDP (TURN service). The container images in their `ejabberd.yml` file use new macros `PORT_TURN_MIN`, `PORT_TURN_MAX`, and `STARTTLS_REQUIRED` that you can setup easily without modifying `ejabberd.yml`, see [macros in environment](https://docs.ejabberd.im/CONTAINER/?ref=process-one.net#macros-in-environment). ## Improved ERL\_DIST\_PORT ejabberd uses [Erlang Distribution](https://docs.ejabberd.im/admin/guide/distribution/?ref=process-one.net) in the [ejabberdctl](https://docs.ejabberd.im/admin/guide/managing/?ref=process-one.net#ejabberdctl) shell script and also for building a cluster of ejabberd nodes. That Erlang Distribution has historically used the [epmd](https://docs.ejabberd.im/admin/guide/distribution/?ref=process-one.net#epmd) program to assign listening ports and discover ports of other nodes to connect. The problems of using epmd are that: - `epmd` must be running all the time in order to resolve name queries - `epmd` listens in port `4369` - the ejabberd node listens in a random port number How to avoid `epmd` since Erlang/OTP 23.1 and ejabberd 22.10 ? Simply set the [ERL\_DIST\_PORT](https://docs.ejabberd.im/admin/guide/distribution/?ref=process-one.net#erl%5Fdist%5Fport) environment variable in the `ejabberdctl.cfg` file: ```sh ERL_DIST_PORT=5210 ``` Since now, `ejabberdctl` passes arguments to Erlang to listen for erlang distribution connections in TCP port 5210, and establish erlang distribution connections to remote ports 5210\. That way you know exactly, in advance, what port number to open in the firewall or container. This ejabberd release introduces some small improvements that facilitate using the `ERL_DIST_PORT` environment variable: - `ejabberdctl` prints an informative message when it detects that there may be a port number collision, which may happen if you start several ejabberd nodes in the same machine listening in the same `ERL_DIST_PORT` and same `INET_DIST_INTERFACE`. - When ejabberd is starting, now it prints the address and port number where it listens for erlang distribution: ``` [info] ejabberd 26.01 is started in the node ejabberd@localhost in 1.90s [info] Elixir 1.19.4 (compiled with Erlang/OTP 28) [info] Erlang/OTP 29 [DEVELOPMENT] [erts-16.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns] [info] Start accepting TCP connections at 0.0.0.0:5210 for erlang distribution [info] Start accepting TCP connections at [::]:5222 for ejabberd_c2s [info] Start accepting TCP connections at [::]:5269 for ejabberd_s2s_in ... ``` - A new [make relivectl](#relivectl) is introduced, which uses `ejabberdctl` script to start ejabberd (not like `make relive`), and starts ejabberd immediately without building a release (not like `make dev`). - The ejabberd Documentation site has improved and updated pages about [Security](https://docs.ejabberd.im/admin/guide/security/?ref=process-one.net), [Erlang Distribution](https://docs.ejabberd.im/admin/guide/distribution/?ref=process-one.net), and [Clustering](https://docs.ejabberd.im/admin/guide/clustering/?ref=process-one.net). ## New make relivectl `make relive` was [introduced in ejabberd 22.05](https://www.process-one.net/blog/ejabberd-22-05/#new-make-relive). It allows to start ejabberd in path `_build/relive/` without installing it, by using `rebar3 shell` and `mix run`. It automatically compiles code at start and [recompiles changed code at runtime](https://www.process-one.net/blog/ejabberd-24-06/#support-for-code-automatic-update). But it doesn't use the `ejabberdctl` script, and doesn't read `ejabberdctl.cfg`, this means that depending on what you are testing, it may not be useful and you had to switch to [make dev](https://docs.ejabberd.im/admin/install/source/?ref=process-one.net#development-release). A new `make` target is now introduced: `make relivectl`. This is similar, as it starts ejabberd without requiring installation, using path `_build/relivectl/` to store the configuration, database and log files. The benefit over `relive` is that `relivectl` uses `ejabberdctl` and reads `ejabberdctl.cfg`. The drawback is that it doesn't recompile code automatically. The benefit over `make dev` is that `relivectl` doesn't build an OTP release, so it's faster to start. Let's summarize all the `make` targets related to installation to determine their usage differences: | make ... | install | install-rel | prod | dev | relivectl | relive | | --------------------- | ------------------------------------------------------------------------------------------------ | -------------- | ----------------------------- | ------------ | ------------------ | --------------- | | Writes files in path | / | / | \_build/prod/ | \_build/dev/ | \_build/relivectl/ | \_build/relive/ | | Installs | ✅ | ✅ | manually uncompress \*.tar.gz | \- | \- | \- | | Uninstall with | uninstall⚠️ [incomplete](https://github.com/processone/ejabberd/issues/1496?ref=process-one.net) | uninstall-rel✅ | manual remove | \- | \- | \- | | Start tool | ejabberdctl | ejabberdctl | ejabberdctl | ejabberdctl | ejabberdctl | rebar3/mix | | Reads ejabberdctl.cfg | ✅ | ✅ | ✅ | ✅ | ✅ | ❌ | | Recompiles | \- | ✅ | ✅ | ✅ | ❌ | ✅ | | Starts ejabberd | \- | \- | \- | \- | ✅ | ✅ | | Recompiles at runtime | \- | \- | \- | \- | ❌ | ✅ | | Execution time (s.) | 13 | 40 | 57 | 35 | 4 | 9 | As seen in the table, `make install / uninstall` seem unnecessary nowadays, because `install-rel / uninstall-rel` allow to install and uninstall correctly all the files. Maybe in the future the implementation of `make install / uninstall` could get replaced with `make install-rel / uninstall-rel`... In the same sense, `make dev` now apparently falls short between `make prod` (which is absolutely indispensable to build a full OTP release) and `make relive/relivectl` (useful, featureful, and fast for development and testing purposes). ## WebAdmin Menu Links Do you remember that [ejabberd 25.07 introduced](https://www.process-one.net/blog/ejabberd-25-07/#link-to-converse-in-webadmin) a link in WebAdmin to the local Converse.js page in the left menu when the corresponding [mod\_conversejs](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fconversejs) is enabled? Technically speaking, until now the WebAdmin menu included a link to the first `request_handler` with `mod_conversejs` that the admin configured in `ejabberd.yml`. That link included the authentication credentials hashed as URI arguments if using HTTPS. Then `process/2` extracted those arguments and passed them as autologin options to Converse. From now, `mod_conversejs` automatically adds a `request_handler` nested in WebAdmin subpath. The WebAdmin menu links to that converse URI; this allows to access the HTTP auth credentials, no need to explicitly pass them. `process/2` extracts this HTTP auth and passes autologin options to Converse. Now scram password storage is supported too. In practice, what does all that mean? Just enable the `mod_conversejs` module, and WebAdmin will have a private Converse URL for the admin, linked in the WebAdmin menu, with autologin. No need to setup a public `request_handler`! For example, let's configure conversejs only for admin usage: ```yaml listen: - port: 5443 module: ejabberd_http tls: true request_handlers: /admin: ejabberd_web_admin /ws: ejabberd_http_ws modules: mod_conversejs: conversejs_resources: "/home/conversejs/12.0.0/dist" ``` Of course, you can setup a public `request_handler` and tell your users to access the corresponding URL: ```yaml listen: - port: 5443 module: ejabberd_http tls: true request_handlers: /admin: ejabberd_web_admin /public/web-client: mod_conversejs /ws: ejabberd_http_ws modules: mod_conversejs: conversejs_resources: "/home/conversejs/12.0.0/dist" ``` With that configuration, what is *the corresponding URL*? Login to the WebAdmin and look at the left menu: now it displays links to all the configured HTTP services: `ejabberd_captcha`, `ejabberd_oauth`, `mod_conversejs`, `mod_http_fileserver`, `mod_register_web`. Also `mod_muc_log_http` and `mod_webpresence` from [ejabberd-contrib](https://docs.ejabberd.im/admin/guide/modules/?ref=process-one.net#ejabberd-contrib) show links in the WebAdmin left menu. Additionally, the menu shows a lock if the page is encrypted HTTPS, and an `!` if it is not. ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for new feature Great Invitations aka `mod_invites` - [Kirill A. Korinsky](https://github.com/catap?ref=process-one.net) and [Greg Troxel](https://github.com/gdt?ref=process-one.net) for `ejabberdctl` support NetBSD and OpenBSD `su` - [Christoph Scholz](https://github.com/ChaosKid42?ref=process-one.net) for fix preload\_rooms in case of SQL-DB - [Mr. EddX](https://github.com/MrEddX?ref=process-one.net) and [Kiril Panayotov](https://github.com/zakrok?ref=process-one.net) for updating the Bulgarian translation - [Sketch6580](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net) for updating the Chinese (Simplified) translation - [poVoq](https://github.com/poVoq?ref=process-one.net), [Nautilusx](https://hosted.weblate.org/user/nautilusx/?ref=process-one.net) and [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for updating the German translation - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for updating the Swedish translation And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get the following changes: - New module `mod_push_gate` that can act as target service for `mod_push`, and which can deliver pushes using configured mod\_gcm or mod\_applepush instances. - New module `mod_push_templates` that can be used to have different push notifications for message class matching configured data patterns. - New database conversion routines targeting p1db backends ## ChangeLog This is a more complete list of changes in this ejabberd release: #### Compile and Start - Remove dependencies, macros and code for Erlang/OTP older than 25 - Require Elixir 1.14 or higher, that's the lowest we can test automatically - `ejabberdctl`: Support NetBSD and OpenBSD `su` ([#4320](https://github.com/processone/ejabberd/issues/4320?ref=process-one.net)) - `ejabberdctl.template`: Show meaningful error when `ERL_DIST_PORT` is in use - `ejabberd_app`: Print address and port where listens for erlang node connections - `Makefile.in`: Add `make relivectl` similar to `relive` but using `ejabberdctl` #### Databases - Add db\_serialize support in mnesia modules - Add db serialization to `mod_muc_sql` - New database export/import infrastructure - Add commands for new database export/import - Apply timestamp pass in `?SQL_INSERT` queries - Update p1\_mysql to bring fix for timestamp decoding - Extend timestamp type handling in sql macros - Revert changes to conversion of pgsql `int` types #### Installer and Container - `make-binaries`: Bump Erlang/OTP 28.3.1 and Elixir 1.19.5 - `Dockerfile`: Bump Erlang/OTP 28.3.1 and Elixir 1.19.5 - `Dockerfile`: Expose also port 7777 for SOCKS5 - `Dockerfile`: Configure TURN ports and expose 5478 50000-50099 - `Dockerfile`: Try to fix error with recent `freetds` Alpine package - Container: Setup new macro `STARTTLS_REQUIRED` to allow easy disabling #### MUC - Add `muc_online_rooms_count` API command - Set `enable_hats` room option `true` by default - Allow vcard queries even when IQ queries are disabled ([#4489](https://github.com/processone/ejabberd/issues/4489?ref=process-one.net)) - Announce `stable-id` feature from XEP-0045 1.31, supported since long ago - Fix `preload_rooms` in case of SQL database ([#4476](https://github.com/processone/ejabberd/issues/4476?ref=process-one.net)) - Run new hooks: `registering_nickmuc` and `registered_nickmuc` ([#4478](https://github.com/processone/ejabberd/issues/4478?ref=process-one.net)) - When deleting account, unregister account's nicks in all MUC hosts ([#4478](https://github.com/processone/ejabberd/issues/4478?ref=process-one.net)) - `mod_muc_log`: Crash in `terminate/2` when stopping module ([#4486](https://github.com/processone/ejabberd/issues/4486?ref=process-one.net)) - `mod_muc_occupantid`: Keep salt per MUC service, not individual rooms - `mod_muc_room`: Rewrite hats code that gets xdata values - `mod_muc_room`: Handle hats without definition ([#4503](https://github.com/processone/ejabberd/issues/4503?ref=process-one.net)) - `mod_muc_room`: When user has no hats, don't store in hats\_users #### WebAdmin - `ejabberd_http`: Run new `http_request_handlers_init` fold hook - `ejabberd_http`: Add helper `get_auto_urls/2` that returns all URLs and TLS - `ejabberd_web_admin`: Add helper functions `make_menu_system` - `ejabberd_web_admin`: Show menu system only when can view vhosts - `ejabberd_web_admin`: Pass Level in `webadmin_menu_system_post` and `inside` hooks - `mod_conversejs`: Improve link to conversejs in WebAdmin ([#4495](https://github.com/processone/ejabberd/issues/4495?ref=process-one.net)) - When epmd isn't running show explanation in Clustering WebAdmin page - Use improved WebAdmin menu system in more modules - When building WebAdmin menu system, `{URLPATH}` in link text is substituted #### Web Services - `rest`: Use separate `httpc` profile - `ejabberd_captcha`: Use `mod_host_meta:get_auto_url/2` - `ejabberd_http`: Support repeated module in request\_handlers - `ejabberd_http`: Get back handling when BOSH or WS are disabled - `mod_host_meta`: Move `get_url` functions from `mod_host_meta` to `ejabberd_http` - `mod_host_meta`: Allow calling `get_url/2` for other modules, not only WebSocket - `mod_host_meta`: Cosmetic rename Module to Handler - `mod_http_upload`: New `content_type` option similar to `mod_http_fileserver` ([#4488](https://github.com/processone/ejabberd/issues/4488?ref=process-one.net)) - `mod_http_upload`: Pass ServerHost, not Host which may be `"upload.HOST"` - `mod_http_upload`: Amend the fix for #4450 to support IDNA correctly ([#3519](https://github.com/processone/ejabberd/issues/3519?ref=process-one.net)) - `mod_http_fileserver`: Support map of paths in `docroot` option - `mod_conversejs`: Add new Conversejs Paths and ContentTypes ([#4511](https://github.com/processone/ejabberd/issues/4511?ref=process-one.net)) - `mod_conversejs`: Use ContentType functions from `mod_http_fileserver` ([#4511](https://github.com/processone/ejabberd/issues/4511?ref=process-one.net)) - Use `/websocket` URL in default configuration like `mod_conversejs`, it's more meaningful #### Core and Modules - Add `replaced_connection_timeout` toplevel option - Fix nasty SSL warnings ([#4475](https://github.com/processon4475e/ejabberd/issues/?ref=process-one.net)) - `ejabberd_commands`: Show meaningul error message when problem executing command ([#4506](https://github.com/processone/ejabberd/issues/4506?ref=process-one.net)) - `ejabberd_logger`: Append "color clean" only in console template, not file - `ejabberd_oauth`: Log error if `oauth_list_tokens` executed with unsupported DB ([#4506](https://github.com/processone/ejabberd/issues/4506?ref=process-one.net)) - `misc`: Get back functions and mark them as deprecated - `mod_adhoc_api`: Show nice command name, as WebAdmin already does - `mod_pubsub`: Deliver pubsub notifications to remote servers for nodes with presence based delivery - `mod_scram_update`: Don't hard-code iteration count - Bump many XEPs versions that are already supported - Improve documentation of `install_contrib_modules` ([#4487](https://github.com/processone/ejabberd/issues/4487?ref=process-one.net)) ### Full Changelog [https://github.com/processone/ejabberd/compare/25.10...26.01](https://github.com/processone/ejabberd/compare/25.10...26.01?ref=process-one.net) ## ejabberd 26.01 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### XMPP integration with n8n URL: https://www.process-one.net/blog/xmpp-integration-with-n8n/ Last updated: 2026-03-19T14:42:36.000Z [n8n](https://n8n.io/?ref=process-one.net) is a platform for workflow automation. Let's see how interface n8n workflows with an XMPP network. As an example on how to use XMPP to receive data from n8n, let's build a simple workflow that publishes into a [MUC room](https://xmpp.org/extensions/xep-0045.html?ref=process-one.net) some information about each commit pushed to a GitHub repository. # Simple workflow to display Git commits in a MUC room You can browse and download this workflow here: [https://share-n8n.net/shared/l6uiZZ54bPC3](https://share-n8n.net/shared/l6uiZZ54bPC3?ref=process-one.net) ![](https://www.process-one.net/content/images/2025/12/Capture-d---e--cran-2025-12-19-a---10.51.34.png) ## GitHub Trigger To receive the information about each Git push, we use the [*GitHub Trigger* node](https://docs.n8n.io/integrations/builtin/trigger-nodes/n8n-nodes-base.githubtrigger/?ref=process-one.net). You need to set up some [GitHub credentials](https://docs.n8n.io/integrations/builtin/credentials/github/?ref=process-one.net) with access to the repository you want to monitor. Then, set the *Repository Owner* and *Repository Name* accordingly. The *Events* you want to receive are of type *Push*. At this point, you can execute the workflow (just containing this unique node), do a couple of commits on your repository, and push them to test that it's received by the GitHub Trigger node. When it works, pin the output data of the node so you don't have to push some more commits while you test the rest of the workflow. Don't forget to unpin it once you want to use the workflow for real. ## Information Formatting As you can see in the output data of the *GitHub Trigger* node, the list of commits in the push are in `body.commits`. We use a [*Split Out* node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.splitout?ref=process-one.net) on this field to process each one of these commits. We then use an [*Edit Fields (Set)* node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/?ref=process-one.net) to format the information we will display about each commit in the final message posted in the MUC room, using a *Manual Mapping*. Just check the input data coming by the previous *Split Out* node to choose what data you want to send to the MUC room. We name the output field `Commit` (type: *String*). Here is an example of such a template: ```javascript "{{ $json.message.split('\n')[0] }}" by {{ $json.author.username }} ({{ $json.author.name }} <{{ $json.author.email }}>), {{ $json.modified.length }} modified file{{ $json.modified.length >1 ? "s" : "" }} ``` The split at the beginning of this example is used to only keep the first line of the commit message. After that, an [*Aggregate* node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.aggregate/?ref=process-one.net) will combine the commits info (one per item) into a single item, with this setting: - *Aggregate*: [Individual Fields](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.aggregate/?ref=process-one.net#individual-fields) - *Input Field Name*: `Commit` (as named in the previous node) As a result, we'll have one item containing the list of commits into a `Commit` field. ## ejabberd credentials We can now send the formatted data to the XMPP server using a [*HTTP Request* node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/?ref=process-one.net). For that, we use the [send\_message command](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#send%5Fmessage) from the ejabberd API. We use an [OAuth](https://docs.ejabberd.im/developer/ejabberd-api/oauth/?ref=process-one.net) token to securely call ejabberd API using [Bearer Authentication](https://swagger.io/docs/specification/v3%5F0/authentication/bearer-authentication/?ref=process-one.net). ### Fluux If you are using a [Fluux instance](https://fluux.io/?ref=process-one.net), you can get an OAuth token from your Fluux console, in the *API Tokens* section. ### Self-hosted ejabberd To create the credentials on your own ejabberd server, you'll need to use the [oauth\_issue\_token command](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#oauth%5Fissue%5Ftoken) to get an OAuth token. Be sure you have an [access rule](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#oauth%5Faccess) that allows you to create such a token. For the scope parameter of `oauth_issue_token` command, use the one defined in your [api\_permissions](https://docs.ejabberd.im/developer/ejabberd-api/permissions/?ref=process-one.net) acl (`ejabberd:admin` in the example below) and be sure the user you issue the token for has the right to call the `send_message` command. Extract of an example of an `ejabberd.yml` file that allows to call `send_message` using OAuth: ```yaml hosts: - "process-one.net" listen: - port: 5281 ip: "::" tls: true module: ejabberd_http request_handlers: "/api": mod_http_api acl: admin: user: - "admin@process-one.net" access_rules: muc: - allow: all muc_create: - allow: local muc_admin: - allow: admin oauth_access: - allow: admin api_permissions: "console commands": from: - ejabberd_ctl who: all what: "*" "admin access": who: - oauth: - scope: "ejabberd:admin" - access: - allow: - acl: admin what: - send_message modules: mod_http_api: {} mod_muc: access: muc access_create: muc_create access_persistent: muc_create access_admin: muc_admin ``` Example of a command to create a token with the above config: ```shell ejabberdctl oauth_issue_token admin@process-one.net 360000 ejabberd:admin ``` ## Sending the XMPP message using send\_message Now you can create your credentials in the *HTTP Request* node: - **Authentication**: [Predefined Credential](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/?ref=process-one.net#predefined-credentials) Type - **Credential Type**: [Bearer Auth](https://docs.n8n.io/integrations/builtin/credentials/httprequest/?ref=process-one.net#using-bearer-auth) - Create a new **Bearer Auth** and put your token in the **Bearer Token** field. For the other fields in the *HTTP Request* node: - **Method**: `POST` - **URL**: Full URL of the `send_message` command as defined by your [ejabberd\_api](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fhttp%5Fapi) listener, for example `https://process-one.net:5281/api/send_message`. If you are using [Fluux](https://fluux.io/?ref=process-one.net), the URL should be `https://NAME.m.in-app.io:5281/api/send_message` where `NAME` is your Fluux instance name. - [**Send Body**](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/?ref=process-one.net#send-body): enabled - [**Body Content Type**](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.httprequest/?ref=process-one.net#json): `JSON` - **Specify Body**: `Using Fields Below` - **Body Parameters**: set the parameters for the [send\_message command](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#send%5Fmessage): - `type`: `groupchat` - `from`: bare JID of the bot that will post the message in the MUC room - `to`: bare JID of the MUC room - `subject`: empty (not relevant for a MUC message) - `body`: template to format the commit information. For example, to display the name of the repository followed by the list of commits, one per line: ```javascript {{ $('Github Push').item.json.body.repository.full_name }} repository: {{ $json.Commit.join("\n") }} ``` The n8n workflow should now be working: it will publish all commits pushed on the repository defined in the first node into the MUC room defined in the last node (don't forget to unpin everything). # Same workflow with a custom stanza You can browse and download this workflow here: [https://share-n8n.net/shared/nxmUMbdNM0gH](https://share-n8n.net/shared/nxmUMbdNM0gH?ref=process-one.net) ![](https://www.process-one.net/content/images/2025/12/Capture-d---e--cran-2025-12-19-a---11.00.28.png) This is a variant of the above workflow to illustrate how to create and send a custom stanza instead of the simple message that `send_message` API permits. This is needed for example if you want to add an element in a custom namespace into your message stanza. The minimal stanza for a [MUC message](https://xmpp.org/extensions/xep-0045.html?ref=process-one.net#message) is: ```xml List of commits ``` We don't need to set the `from`, `to` or `id` attribute, it will be handled by the API call done in the last node. Let's say we want to add a sub-tab containing the timestamp of the moment the message was sent by n8n. The stanza we want to create looks like this: ```xml List of commits 2025-12-17T11:16:13.071-05:00 ``` ## Create a custom stanza We want to create that stanza just before the last one, between the *Aggregate* node and the *HTTP Request* node. To ensure that all strings from the git commit are correctly encoded for XML, we use the [**JSON to XML** node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.xml/?ref=process-one.net). This means we have to construct the stanza in JSON first. This is done in the **Make Stanza in JSON** node of type [*Edit Fields (Set)*](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.set/?ref=process-one.net). We use the *Manual Mapping* to ensure all special characters from the git commit are correctly escaped. - We set a `$` field (which is the default [**Attribute Key**](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.xml/?ref=process-one.net)) to set the **type** attribute on the root element. The name of the root element, `message`, will be set in the next node, **JSON to XML**. - We create a `body` field of type *String* that will contain the list of commits, one per line. We can use the same template used in the last node of the previous workflow: ```javascript {{ $('Github Push').item.json.body.repository.full_name }} repository: {{ $json.Commit.join("\n") }} ``` - We add a `n8n` field for the custom tag, with type `Object`, to be able to set a `xmlns` attribute on it: ```json { "_": "{{ $now }}", "$": {"xmlns": "p1:custom:timestamp"} } ``` ## Convert the stanza in XML The stanza is converted in XML in the **Convert stanza in XML**, *XML* node: - The **Mode** is *JSON to XML* - **Property Name** is the name of the field in the output data, let's name it `stanza`. - We have to enable the **Headless** option to prevent the XML header to be added before the message. - The **Root Name** is set to `message` (the root element of the stanza) as the JSON received from the previous node is just the content of the XML document. ## Sending the XMPP message using send\_stanza The configuration of the *HTTP Request* node is the same than for the previous workflow, except that the URL must call [send\_stanza](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#send%5Fstanza) instead of `send_message`. The `body` parameter is replaced by the `stanza` one, in which we just have to set the `stanza` field from the previous node: ```json {{ $json.stanza }} ``` Be sure to adapt your ejabberd configuration accordingly, specifically to allow `send_stanza` to be called. ### Enabling Fluux.io WebPush on a PWA on iOS URL: https://www.process-one.net/blog/enabling-fluux-io-webpush-on-a-pwa-on-ios/ Last updated: 2026-01-06T09:58:15.000Z As we previously described [here](https://www.process-one.net/blog/webpush-support-on-your-fluux-io-instance/), your Fluux.io service can send push notifications to your xmpp user's browsers when they are offline. It includes Safari on iOS devices. But before enabling it your users need to add your Progressive Web App (PWA) on their home screen. You can test the whole process with our "Test Client" from your fluux.io console. First, sign in fluux.io console and go to WebPush App list. Like in previous blog post open test client. ![](https://www.process-one.net/content/images/2025/12/Photo-15-12-2025--17-32-09.png) This page has a link tag : `` linking to a WebApp manifest file such this one [https://fluux.io/manifest.json](https://fluux.io/manifest.json?ref=process-one.net) We reproduced here main fields : ``` { "name": "FluuxIO", "icons": [ { "src": "/logo.png", "type": "image/png", "sizes": "200x200" } ], "display": "standalone" } ``` This file provides a name, an icon and so on to the PWA. It also fixes display mode to "standalone" which is required to enable push notification on a Progressive Web App on iOS. With such configuration, end-user has to tap on "share button" : ![](https://www.process-one.net/content/images/2025/12/Photo-11-12-2025--11-30-13-1.png) Then iOS user has to scroll and tap on "Add to Home Screen". ![](https://www.process-one.net/content/images/2025/12/Photo-11-12-2025--11-32-47.png) It will open a form prefilled with data from manifest.json ![](https://www.process-one.net/content/images/2025/12/Photo-11-12-2025--11-33-03.png) Once registration form submitted, a new icon will appear on iOS device home screen and will act as a new app. ![](https://www.process-one.net/content/images/2025/12/Photo-11-12-2025--11-30-01.png) Launch it, sign in your fluux console, and move back to test client and connect using a test user. You can now tap on "Enable webpush" ![](https://www.process-one.net/content/images/2025/12/Photo-11-12-2025--11-33-54.png) You will be prompted to allow your device to receive push notification from your fluux platform (through safari/apple server). ![](https://www.process-one.net/content/images/2025/12/Photo-11-12-2025--11-34-47.png) Like other push worflows a notification for new message will be sent to xmpp user's device when offline : ![](https://www.process-one.net/content/images/2025/12/Photo-11-12-2025--11-40-09.png) ### Stop Telling Us XMPP Should Use JSON URL: https://www.process-one.net/blog/stop-telling-us-xmpp-should-use-json/ Last updated: 2025-11-25T15:25:23.000Z We hear this too often: “XMPP uses XML. It should use JSON—it’s more modern.” The logic seems straightforward: JSON came later, so it must be better. But better for what, exactly? JSON became successful because it’s the standard serialization format for JavaScript. That made it convenient for browser-based applications. Does that make it the universal format for every protocol? Of course not. Consider this: browsers still use HTML to organize web pages, not JSON. Same with CSS. Why? Because using JSON for everything would be a nightmare. XML remains the best format for representing trees—deep hierarchies of nested data. JSON handles flatter structures well, but good messaging protocols are extensible: extensions can be embedded at different levels and composed together, like Lego bricks. That’s where XML shines. ## The Performance Myth Another common claim: XMPP’s XML is more complex than JSON, so it must be much slower. In practice, XMPP chat platforms are snappier, with remarkably low message latency. How? XMPP clients don’t parse XML the way most people assume. They’re not building massive DOM trees in memory, like a browser loading a page. Instead, they use stream-based parsing—XML arrives, gets parsed incrementally, and converts directly into native data structures. This is especially true in browser environments, where XMPP streams run over WebSockets, which naturally frames the XMPP protocol. That’s why you are never actually working with XML trees consuming large chunks of memory. Modern implementations like XMPP.js go further and use LTX—a lightweight parser built specifically for XMPP’s streaming model—rather than the browser’s DOM parser. The result: developers work with JSON-like objects anyway. The wire format becomes invisible to your application code. XML brings three key advantages: - Built-in **extensibility** with validation via XML Schemas - Clean namespace management for XEPs: when the protocol needs to evolve, you can change the namespace of an extension, making **versioning** explicit and backward compatibility manageable - 25+ years of **mature tooling** and battle-tested parsers These matter when you’re building federated systems that need to evolve over time and need to stay compliant over time. The XMPP federation is a huge ecosystem of servers that can talk to each other, relying on different server implementations and are not always up to date. Still, the federation works, and we too often forget that this is a great achievement in itself. Real performance bottlenecks in XMPP deployments come from elsewhere entirely: network latency, database optimization for roster and message storage, custom module performance, external components, or clustering and routing logic. The myth persists because XML looks verbose when you read it. But visual verbosity has almost no correlation with parsing performance. Modern CPUs parse XML and JSON at nearly identical speeds for typical XMPP message sizes. Any difference vanishes in a real-world client. ## Where the Real Complexity Lives XMPP does have genuine complexity—but it’s not the wire format. It’s the protocol depth and the extensive XEP ecosystem with hundreds of extensions. That’s a real learning curve. Consider XMPP when these factors matter to you: - **Federation** across organizational boundaries - **Open standards** and avoiding vendor lock-in - Protocol **stability** that won’t break in three years - **Extensibility** without forking the protocol If those resonate, the wire format should be the least of your concerns. We’ve been building XMPP systems for over 25 years. The XML performance question comes up often in early conversations. Every single time, we end up optimizing ejabberd configuration, clustering, architecture, client protocol usage, and databases instead. Thinking about XMPP for your next project? [Reach out](https://www.process-one.net/contact/) during the design phase. We’ll help you avoid the actual bottlenecks. ### On Signal Protocol and Post-Quantum Ratchets URL: https://www.process-one.net/blog/on-signal-protocol-and-post-quantum-ratchets/ Last updated: 2025-11-10T14:10:11.000Z Signal improved its protocol to prepare encrypted messaging for the quantum era. They call the improvement “Triple Ratchet” (or SPQR = Signal Post-Quantum Ratchet). [Signal Protocol and Post-Quantum RatchetsWe are excited to announce a significant advancement in the security of the Signal Protocol: the introduction of the Sparse Post Quantum Ratchet (SPQR). This new ratchet enhances the Signal Protocol’s resilience against future quantum computing threats while maintaining our existing security guar…![](https://www.process-one.net/content/images/icon/apple-touch-icon-1.png)Signal Messenger![](https://www.process-one.net/content/images/thumbnail/spqr-opengraph.png)](https://signal.org/blog/spqr/?ref=process-one.net) If history repeats itself, this could become the next open standard for secure messaging. Signal (formerly Open Whisper Systems) created the [Double Ratchet algorithm](https://en.wikipedia.org/wiki/Double%5FRatchet%5FAlgorithm?ref=process-one.net) in 2013–2014, introduced in TextSecure v2 in February 2014\. They packaged it into the open source Signal Protocol. It became the mainstream standard for end-to-end encrypted messaging. XMPP adopted it ([OMEMO](https://xmpp.org/extensions/xep-0384.html?ref=process-one.net), first drafted in 2015). Matrix adopted it (Olm/Megolm implements Double Ratchet concepts). The problem is that current encryption methods could break when quantum computers get powerful enough, so Signal built Triple Ratchet to protect against that. Most messaging companies are preparing for this but I noticed that WhatsApp has no public roadmap for the adoption of quantum resistance protocols. They use the Signal Protocol for encryption, so they may simply wait for the result of Signal’s work to adopt the new approach. It is much heavier to implement, so I am wondering if Triple Ratchet follows the same path as Double Ratchet and gets widespread adoption. If open protocols like XMPP and Matrix adopt it, it may be huge for European messaging independence. What’s your take? Do you think quantum resistance will become a mandatory feature for end-to-end encrypted messaging platforms in the next couple of years? ### Europe’s Decentralized Messaging Survives “Chat Control” Threat URL: https://www.process-one.net/blog/decentralized-messaging-survives-chat-control-threat/ Last updated: 2025-11-03T17:24:35.000Z Good news for anyone building messaging infrastructure in Europe: Denmark's Council presidency is abandoning mandatory detection orders in the Child Sexual Abuse Material (CSAM) proposal for now. The proposal was nicknamed "Chat Control" because it was invasive, requiring platforms to scan all message content. To do that, it would have required bypassing end-to-end encryption, practically creating a surveillance infrastructure. They gave up after Germany and other EU countries blocked the message scanning obligation. They abandoned plans to put the text to a vote in the Council of the European Union in October as they had hoped. Now, they [propose to return to the previous status quo](https://www.euractiv.com/news/danish-presidency-backs-away-from-chat-control/?ref=process-one.net). It's a relief for companies working on open and standards-based infrastructure. As I've already explained, [mandatory scanning is technically impossible to enforce for federated protocols like XMPP and Matrix](https://www.process-one.net/blog/chat-control-2025). Europe's decentralized messaging ecosystem would have been threatened, and the law would have been ineffective at preventing illegal data exchange, as encryption can always be applied outside of the chat application. I know this is the type of fight that is never really over, but still, it is nice to see that sometimes sanity can prevail. ### AI Bots Can't Use WhatsApp Anymore. So... Who Are They Going to Talk To? URL: https://www.process-one.net/blog/ai-bots-cant-use-whatsapp-anymore/ Last updated: 2025-10-31T14:51:42.000Z Meta just closed the gates on AI chatbots. I think this is an early warning. Starting January 15, 2026, [WhatsApp will ban all third-party general-purpose AI chatbots from its platform](https://techcrunch.com/2025/10/18/whatssapp-changes-its-terms-to-bar-general-purpose-chatbots-from-its-platform/?ref=process-one.net). ChatGPT, Perplexity, Poke, they'll all be gone. The only general-purpose AI you'll find on WhatsApp? Meta AI. Meta's stated reason: these bots place a "burden on its systems and support teams." The real reason is more likely control, of course. *But here's what makes this fascinating:* While Meta is locking down WhatsApp, Discord—which has no AI ambitions of its own—just raised its server capacity to 25 million users. Why? Because Midjourney, a third-party AI tool, built its entire interface on Discord and now has over 20 million members in a single server. Discord didn't build the AI. They just provided the platform. And they're reaping the rewards. *Two platforms, two strategies, leading to two very different futures.* Meta is betting that owning both the AI layer and the communication layer is the path to dominance. Discord is betting that being the best platform for AI, even AI they don't control, creates more value. I feel like we're watching a pattern repeat itself. We already fought the battle for open communication protocols. First we won, and then, in the consumer arena at least, we lost. Today we juggle a dozen incompatible messaging apps because federation was abandoned in favor of walled gardens. Now the same battle is starting again, but this time it's about AI agent interoperability and since AI interfaces are often chat-based today, the lock-in on messaging creates an opportunity to expand that lock-in to AI agents. *It will be like a new app store monopoly all over again.* Will your company's procurement agent be able to negotiate with a supplier's logistics agent if they're built on different platforms? Will healthcare AI be able to securely federate across hospital systems? Or will we lock ourselves into incompatible agent ecosystems controlled by whoever moves fastest? *The IETF is starting to draft standards for agent-to-agent protocols. The A2A initiative is pushing for interoperability. But the window is closing.* If we don't act now, while these protocols are still being designed, we'll spend the next 20 years trying to regulate our way out of another fragmented mess. *I've been thinking about this for a while. More coming soon.* But for now, ask yourself: Do we want platforms that lock out third-party AI agents (the Meta approach) or platforms that allow them to thrive (the Discord approach)? Here's what's really at stake: Today's decisions aren't just about which apps we use. They're about whether AI agents themselves will be able to work across platforms and companies, or whether we'll fragment into incompatible ecosystems all over again. --- *So, what do you think? Should AI agents be able to work across platforms, or is vendor lock-in really inevitable?* ### 🚀 ejabberd 25.10 URL: https://www.process-one.net/blog/ejabberd-25-10/ Last updated: 2025-10-31T14:11:56.000Z **Release Highlights:** - **[Added more Ad-Hoc Commands from XEP-0133](#adhoc)** - **[Updated support for XEP-0317 Hats](#hats)** If you are upgrading from a previous version, there are no mandatory changes in SQL schemas, configuration, API commands or hooks. **Other contents:** - **[New option archive\_muc\_as\_mucsub in mod\_mam](#mucsub)** - **[Removed support for Erlang/OTP older than 25.0](#erlang25)** - **[Support for the new Erlang maybe expression](#maybe)** - **[Rename New SQL schema to Multihost, and Default to Singlehost](#multihost)** - **[Improved GitHub Workflows](#workflows)** - **[Acknowledgments](#ack)** - **[Improvements in ejabberd Business Edition](#ebe)** - **[ChangeLog](#changelog)** - **[ejabberd 25.10 download & feedback](#download)** Below is a detailed breakdown of the improvements and enhancements: ## New option archive\_muc\_as\_mucsub in mod\_mam When this option is enabled incoming groupchat messages for users that have MucSub subscription to a room from which message originated will have those messages archived after being converted to mucsub event messages. ## Removed support for Erlang/OTP older than 25.0 The [ejabberd 24.12 release announcement](https://www.process-one.net/blog/ejabberd-24-12/#erlang25) explained that support for Erlang/OTP older than 25.0 was discouraged, it would be deprecated in future releases, and completely removed sometime after ejabberd 25.01\. That explanation was mentioned several times in the subsequent ejabberd releases. The initial reason to require Erlang/OTP 25 was that this version is the lowest we can easily use nowadays for running the [CI tests](https://github.com/processone/ejabberd/actions/workflows/ci.yml?ref=process-one.net). Other reasons to remove support for Erlang lower than 25 are: to support `maybe` expression, and to remove duplicate code. In order to support both new and very old Erlang/OTP versions, ejabberd source code included many duplicate code. All that duplicate code that is nowadays useless will be removed in a future ejabberd release. ## Support for the new Erlang 'maybe' expression The new `maybe` expression is supported since Erlang/OTP 25 (requires being enabled), and it is enabled by default since 27. Now that ejabberd requires Erlang/OTP 25, and it enables the `maybe` expression, this can be used freely in ejabberd source code and modules. See: - Erlang Documentation: [maybe Expression](https://www.erlang.org/doc/system/expressions.html?ref=process-one.net#maybe) - [EEP 49: Value-Based Error Handling Mechanisms](https://www.erlang.org/eeps/eep-0049?ref=process-one.net) ## Rename 'New' SQL schema to 'Multihost', and 'Default' to 'Singlehost' When ejabberd first got support for SQL storage, it only supported one vhost, so it made sense to **not** store the host in the SQL tables. Additionally, the SQL schema in ejabberd followed that of jabberd14, which didn't support multiple vhosts either. When ejabberd got support for multiple vhosts, if several of them want to use SQL storage, the solution is to configure a different SQL database for each vhost using the `host_config` toplevel option. However, when there are many vhosts configured in ejabberd, all of them using SQL storage, it is preferable to setup one single SQL database, and store the vhost in the tables. When that feature was added to ejabberd, it got the name of "new SQL schema". And the previous SQL schema was called "legacy", "old", and nowadays "default". The problem with the terms "default" and "new" is that they are circumstantial, and do not really describe the schema features or purposes. Now those terms have been renamed: - "default SQL schema" ⟹ "singlehost SQL schema" - "new SQL schema" ⟹ "multihost SQL schema" Right now all names are supported, the previous (obsolete) and the renamed (preferred). No changes are needed in your existing configuration file or building instructions, but it is preferable if you can update your setup to the new terms: When preparing configuration, the old and new arguments are: ``` ./configure --enable-new-sql-schema ./configure --enable-multihost-sql-schema ``` When configuring ejabberd, the old and new toplevel options are: ``` new_sql_schema: true sql_schema_multihost: true ``` When developing source code, the old and new functions are: ``` ejabberd_sql:use_new_schema() ejabberd_sql:use_multihost_schema() ``` ## New API Commands Several ejabberd modules implement new API Commands, most of them inspired by [XEP-0133](https://xmpp.org/extensions/xep-0133.html?ref=process-one.net): - `ejabberd_admin`: - [restart\_kindly](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#restart%5Fkindly) - [mod\_admin\_extra](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fadmin%5Fextra): - [count\_banned](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#count%5Fbanned) - [list\_banned](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#list%5Fbanned) - [mod\_announce](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fannounce): - [announce\_motd\_delete](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fdelete) - [announce\_motd\_get](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fget) - [announce\_motd\_set\_online](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fset%5Fonline) - [announce\_motd\_update](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fupdate) - [announce\_send\_all](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fsend%5Fall) - [announce\_send\_online](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fsend%5Fonline) - [mod\_muc\_admin](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmuc%5Fadmin): - [muc\_get\_registered\_nick](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#muc%5Fget%5Fregistered%5Fnick) - [muc\_get\_registered\_nicks](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#muc%5Fget%5Fregistered%5Fnicks) ## Added more Ad-Hoc Commands from XEP-0133 [XEP-0133](https://xmpp.org/extensions/xep-0133.html?ref=process-one.net#usecases) describes 31 administrative tasks that should be available as ad-hoc commands. ejabberd already implemented many of those ad-hoc commands in [mod\_configure](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fconfigure), but there were a few missing that nowadays are fairly easy to implement: this new ejabberd release supports all of them... except 5. The five ad-hoc commands from XEP-0133 that are not supported are: - `6. Get User Password`, because it was already retracted in the XEP and should not be implemented - `12. Edit Whitelist`, because the corresponding feature is not implemented in ejabberd - `27. Set Welcome Message`, because in ejabberd this message is set in the configuration file, option `welcome_message` of [mod\_register](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fregister) - `28. Delete Welcome Message`, for similar reason - `29. Edit Admin List`, because in ejabberd the administrative rights to accounts are granted in the configuration file, toplevel option `acl`. On the other hand, ejabberd implements more than [200 API commands](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net) in all over its source code, providing those and many other administrative tasks. And you can execute those API commands using the command line, ReST calls, XML-RPC, WebAdmin, ... and ad-hoc commands too!!! See the available [API frontends](https://docs.ejabberd.im/developer/ejabberd-api/?ref=process-one.net#api-frontends). Nowadays, all the ad-hoc commands described in XEP-0133 have a similar API command in ejabberd that you can execute using ad-hoc commands too: | Ad-hoc command in XEP-0133 | Status in ejabberd 25.10 | Equivalent [API command](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net) | | --------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | | Add User | 〽️ (no vCard arguments) | [register](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#register) | | Delete User | ✅ | [unregister](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#unregister) | | Disable User | ✅ | [ban\_account](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#ban%5Faccount) | | Re-Enable User | ✅ | [unban\_account](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#unban%5Faccount) | | End User Session | 〽️ (argument) | [kick\_session](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#kick%5Fsession) | | Get User Password (retracted) | ▶️ (retracted) | [check\_password](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#check%5Fpassword) | | Change User Password | ✅ | [change\_password](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#change%5Fpassword) | | Get User Roster | 〽️ (result syntax) | [get\_roster](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get%5Froster) | | Get User Last Login Time | ✅ | [get\_last](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get%5Flast) | | Get User Statistics | ✅ | [user\_sessions\_info](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#user%5Fsessions%5Finfo) | | Edit Blacklist | ▶️ | [add\_blocked\_domain](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#add%5Fblocked%5Fdomain) | | Edit Whitelist | ❌ | \- | | Get Number of Registered Users | ✅ | [stats](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#stats) | | Get Number of Disabled Users | ✅ | [count\_banned](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#count%5Fbanned) | | Get Number of Online Users | ✅ | [stats](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#stats) | | Get Number of Active Users | ✅ | [status\_num](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#status%5Fnum) | | Get Number of Idle Users | ✅ | [status\_num](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#status%5Fnum) | | Get List of Registered Users | ✅ | [registered\_users](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#registered%5Fusers) | | Get List of Disabled Users | ✅ | [list\_banned](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#list%5Fbanned) | | Get List of Online Users | ✅ | [connected\_users](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#connected%5Fusers) | | Get List of Active Users | ✅ | [status\_list](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#status%5Flist) | | Get List of Idle Users | ✅ | [status\_list](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#status%5Flist) | | Send Announcement to Online Users | ✅ | [announce\_send\_online](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fsend%5Fonline) | | Set Message of the Day | ✅ | [announce\_motd\_set\_online](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fset%5Fonline) | | Edit Message of the Day | ✅ | [announce\_motd\_update](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fupdate) | | Delete Message of the Day | ✅ | [announce\_motd\_delete](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#announce%5Fmotd%5Fdelete) | | Set Welcome Message | ▶️ | (option welcome\_message in [mod\_register](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fregister)) | | Delete Welcome Message | ▶️ | (option welcome\_message in [mod\_register](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fregister)) | | Edit Admin List | ▶️ | (option [acl](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#acl)) | | Restart Service | ✅ | [restart\_kindly](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#restart%5Fkindly) | | Shut Down Service | ✅ | [stop\_kindly](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#stop%5Fkindly) | Status legend: - ✅ Implemented in ejabberd exactly as XEP-0133 describes it - 〽️ Implemented with same command name, but different arguments or results - ▶️ Not implemented as XEP-0133 says, but we have an alternative solution - ❌ Not implemented in ejabberd in any way ## Updated support for XEP-0317 Hats Support for [XEP-0317 Hats](https://xmpp.org/extensions/xep-0317.html?ref=process-one.net) is improved from 0.2.0 to the latest 0.3.1. Previously, the XEP lacked some use cases, and ejabberd implemented them as custom additional features, as documented in [MUC Hats](https://docs.ejabberd.im/tutorials/muc-hats/?ref=process-one.net). Now that the XEP includes all those additions, ejabberd strictly follows XEP-0317 version 0.3.1. ## Improved GitHub Workflows The ejabberd git repository contains [several GitHub Workflows](https://github.com/processone/ejabberd/tree/master/.github/workflows?ref=process-one.net) to test automatically the source code with static and dynamic tools, build installers and containers. Those workflows recently got several improvements: - Run agnostic-database tests only once, not for every backend - Add local composite actions to manage ejabberd and databases - Reorganize steps in the CI workflow to run in parallel jobs - Use ARM runners to build ARM installers and containers, no need for cross compiling - Use ARM runners instead of x86 when possible, as they run faster - Cache dependencies and download from CDNs when possible With all those improvements, the workflows complete (or give some error report) in less than 10 minutes, instead of the 30 minutes that were common before. For details about those changes, check [PR 4460](https://github.com/processone/ejabberd/pull/4460?ref=process-one.net) ## Acknowledgments We would like to thank the contributions to the source code provided for this release by: - [Guus der Kinderen](https://github.com/guusdk?ref=process-one.net) for update XMPP-Interop-Testing - [Holger Weiß](https://github.com/weiss?ref=process-one.net) for mod\_push cosmetic changes - [marc0s](https://github.com/marc0s?ref=process-one.net) for the new `push_send_notification` hook - [Pouriya Jahanbakhsh](https://github.com/pouriya?ref=process-one.net) for pass HTTP headers from WS to C2S connection - [Yurt Page](https://hosted.weblate.org/user/yurtpage2/?ref=process-one.net) for updating the Russian translation And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get the following changes: - The `bulk_roster_update` API command now accept a list of groups. - The `mod_dedup` module has been improved to handle received markers. This module was added in 4.2508 to prevent both delivery and storage of duplicates in archive. - Fixed a case where a mobile client was not able to retrieve all the messages received while it was offline after a temporarily loses of its data connection. ## ChangeLog This is a more complete list of changes in this ejabberd release: #### Ad-hoc Commands - `mod_configure`: New ad-hoc commands that were missing from XEP-0133 - `mod_adhoc_api`: Add support for asynchronous command calling - `mod_adhoc_api`: If argument is a list of jids, type is `jid-multi` - `mod_adhoc_api`: If field has several values, type is `text-multi` #### API Commands - Add commands argument type `binary_or_list` - `mod_http_api`: Format sub elements for tuples from maps - `mod_admin_extra`: Improve roster API commands documentation - `mod_announce`: New API commands, reusing existing ad-hoc functions - `ejabberd_admin`: New API command `restart_kindly`, improve `stop_kindly` - `mod_admin_extra`: New API commands `list_banned` and `count_banned` - `mod_admin_extra`: Improve API command `status_list`: support for status to be a list - `mod_muc_admin`: New API commands `muc_get_registered_nick` and nicks ([#4468](https://github.com/processone/ejabberd/issues/4468?ref=process-one.net)) - Use `mod_private:del_data` in `unban_account` API command #### Configuration - Rename `New` SQL schema to `Multihost`, and `Default` to `Singlehost` ([#4456](https://github.com/processone/ejabberd/issues/4456?ref=process-one.net)) - Add config transformer from `use_new_schema` \-> `sql_multihost_schema` - `mod_sip`: Fix problem parsing `via` in `yconf` library ([#4444](https://github.com/processone/ejabberd/issues/4444?ref=process-one.net)) #### Erlang/OTP support - Enable feature `maybe_expr` in the compiler for Erlang/OTP 26 ([#4459](https://github.com/processone/ejabberd/issues/4459?ref=process-one.net)) - Enable feature `maybe_expr` also in the runtime for Erlang/OTP 25 - Runtime: Remove Erlang 24 which won't work anymore with `maybe_expr` - Remove `EX_RULE` and `EX_STACK` macros only used with ancient erlang #### GitHub Workflows - CI: Bump XMPP-Interop-Testing/xmpp-interop-tests-action ([#4469](https://github.com/processone/ejabberd/issues/4469?ref=process-one.net)) - CI: Don't care to include commit details in the CT logs HTML page - CI and Runtime: Reorganize steps to run in parallel, and ARM runner ([#4460](https://github.com/processone/ejabberd/issues/4460?ref=process-one.net)) - Add local composite actions to manage ejabberd and databases - Container: Build ARM in native runner instead of QEMU, merge and clean - Installers: Generate ARM installers in native runner - Tests: Run agnostic-database tests only once, not for every backend - Tests: The odbc backend is not actually used in Commont Tests - Weekly: New workflow that condenses CI, test all erlang without caching #### Installers and Containers - Bump Erlang/OTP version to 27.3.4.3 in installers and container - Bump Expat 2.7.3, OpenSSL 3.5.4, unixODBC 2.3.14 in installers #### MUC - `mod_mam`: New option `archive_muc_as_mucsub` - `mod_muc`: Check if room is hibernated before calling mod\_muc process - `mod_muc`: Update implementation of XEP-0317 Hats to version 0.3.1 ([#4380](https://github.com/processone/ejabberd/issues/4380?ref=process-one.net)) - `mod_muc`: Make mod\_muc\_sql properly handle new hats data ([#4380](https://github.com/processone/ejabberd/issues/4380?ref=process-one.net)) - `mod_muc_room`: Don't require password if user is owner of room - `mod_muc_admin`: Use in WebAdmin the new API commands that get nick registers #### Core and Modules - `ejabberd_http_ws`: Pass HTTP headers from WS to C2S connection ([#4471](https://github.com/processone/ejabberd/issues/4471?ref=process-one.net)) - `ejabberd_listener`: Properly pass `send_timeout` option to listener sockets - `ejabberdctl`: When ping returns pang, return also status code 1 ([#4327](https://github.com/processone/ejabberd/issues/4327?ref=process-one.net)) - `ext_mod`: Print module status message after installation - `misc`: json\_encode should always call json with our filter - `mod_admin_update_sql`: Use same index name than when creating database - `mod_block_strangers`: Clarify `access` and `captcha` documentation ([#4221](https://github.com/processone/ejabberd/issues/4221?ref=process-one.net)) - `mod_http_upload`: Encode URL before parsing, as done before `bba1a1e3c` ([#4450](https://github.com/processone/ejabberd/issues/4450?ref=process-one.net)) - `mod_private`: Add `del_data/3`, `get_users_with_data/2`, `count_users_with_data/2` - `mod_pubsub`: Don't catch `exit:{aborted, _}` inside mnesia transactions - `mod_push`: Run new hook `push_send_notification` ([#4383](https://github.com/processone/ejabberd/issues/4383?ref=process-one.net)) - WebAdmin: Respect newline and whitespace characters in results ### Full Changelog [https://github.com/processone/ejabberd/compare/25.08...25.10](https://github.com/processone/ejabberd/compare/25.08...25.10?ref=process-one.net) ## ejabberd 25.10 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Europe's Digital Sovereignty Paradox - "Chat Control" update URL: https://www.process-one.net/blog/chat-control-update-oct-2025/ Last updated: 2025-10-13T15:16:42.000Z October 14th was supposed to be the day the European Council voted to **mandate scanning of all private communications**, encrypted or not. *The vote was pulled at the last minute.* Germany withdrew support, creating a blocking minority that blocked the Danish Presidency's hope to get the text approved. Denmark still hopes to push this through by the end of its EU presidency in December. I personally would like to be optimistic and think that **the tech community managed to raise enough concerns** with EU policymakers. **Hundreds of European companies** such as Proton, NordVPN, Tuta, Murena, Element, ProcessOne voiced their concernsabout Chat Control. These companies are building the European alternatives we need for digital sovereignty. They offer what the EuroStack coalition is demanding: **local infrastructure, values-driven technology, independence from US hyperscalers**. And EU policy trying to force them to break the very protocols that make sovereignty possible does not seem like the wisest strategic move. What policymakers are missing is that encryption is a **built-in foundation of most communication protocols**. You cannot turn it on or off depending on what is considered right in a given place at a given moment. **You either have secure end-to-end encryption or you don't.** There is no "just this once" exception that doesn't become an exploitable technical or administrative vulnerability. When Denmark's Justice Minister suggested that the "completely misguided perception" is that everyone has a right to secure communication, he revealed the fundamental gap: policymakers who don't understand that secure infrastructure is the core of today's Internet backbone, not just for the pure sake of democracy (I swear it hurts to have to explain this), but also for the existential security of European countries. Today, European countries are prioritizing defense spending while missing that digital infrastructure *is* the battlefield. Networks allow us to control drones, spread misinformation, they are vectors of attacks on critical infrastructure. It is time for Europe to develop a **coherent tech strategy**. Can we build digital sovereignty while simultaneously undermining the protocols that enable it? Can we demand independence from US tech giants while forcing European alternatives to adopt vulnerabilities that US companies will try to avoid through commercial pressure? The October postponement is an opportunity. Two months for actual infrastructure builders and engineers to inform policy. Two months to bridge the gap between Brussels' political vision and the technical reality of how secure systems actually work. **This is exactly the gap I work to bridge:** between policymakers who understand the geopolitical stakes and engineers who understand protocol layers. Europe's path to digital sovereignty requires both. Denmark's December push will show us whether Europe is serious about learning from its own technical community, or whether we're condemned to keep making policy that contradicts our stated goals. **The European way should be: tech with purpose, built on sound engineering, serving democratic values.** Not tech policy that undermines the very infrastructure we need to achieve independence. ### Why Europe's 'Chat Control' Proposal Will Cripple European Communication Industry While Failing to Protect Children URL: https://www.process-one.net/blog/chat-control-2025/ Last updated: 2025-09-26T13:08:49.000Z On October 14th, the European Concil will vote on a regulation that could effectively dismantle Europe's emerging decentralized messaging ecosystem, and shake the broader European communication industry while failing to protect the children it claims to defend. Driven by Denmark's fierce advocacy during its EU presidency, **proposal 11596/25** – labeled 'Chat Control' by privacy advocates – finally faces a decisive moment after years of debate. The proposal seems straightforward: require platforms to scan for child sexual abuse material. But the technical reality reveals a **devastating contradiction**: it demands the impossible from open, federated European alternatives while handing structural advantages to the very US tech giants Europe claims to want to regulate. ## What the proposal actually requires Proposal 11596/25 targets child sexual abuse material across a large range of services operating in the European Union: hosting services, interpersonal communications services, software application stores, internet access services, and online search engines. Under this regulation, these providers would be required to detect illegal content (images, URLs, text), report it to authorities, and remove it. The scope goes far beyond what the European Parliament previously considered acceptable. In its balanced approach to child protection, Parliament explicitly rejected *"widespread web scanning, blanket monitoring of private communications or the creation of backdoors in apps to weaken encryption."* See: [How the EU is fighting child abuse online](https://www.europarl.europa.eu/topics/en/article/20231116STO11629/how-the-eu-is-fighting-child-sexual-abuse-online?ref=process-one.net). This proposal abandons that restraint. It creates an obligation for service providers to scan all user traffic – encrypted or not – in search of illegal materials. More critically, **it requires scanning private chat conversations** before content is encrypted, not just publicly available content. ## The risk of surveillance overreach While child protection is undeniably crucial, the surveillance mechanisms described in this regulation create infrastructure that could **threaten fundamental civil liberties**. Once governments possess the technical capability to scan all private communications before encryption, the temptation to expand its use becomes overwhelming. The concern isn't about protecting illegal content, it's about protecting democratic discourse. Private conversations could become subject to monitoring based on shifting political definitions of harmful speech. What begins as child protection infrastructure could evolve into a tool for suppressing political opposition or monitoring dissenting opinions in private communications. The infrastructure created for child protection becomes the foundation that future governments — potentially less democratic ones — could leverage to monitor any communications they consider threatening to their power. This is what privacy advocates primarily focus on, and their concerns are valid. However, as operators of messaging infrastructure, we face more immediate technical realities that make this regulation unworkable regardless of its civil liberties implications. ## Why the technical requirements are impossible to implement As operators of XMPP messaging infrastructure in sensitive industries, like for example the medical sector, we face the practical reality of what this regulation would require. The technical demands in Articles 7 and 10 reveal fundamental misunderstandings about how modern communication systems actually work. ### The architectural reality: In-band vs. out-of-band content Modern messaging platforms fundamentally separate data types. Messages and protocol data transfer "in-band" through the messaging protocol, while binary content like images and documents transfers "out-of-band" because files are too large for messaging channels. This creates an immediate problem for the regulation's scanning requirements. When doctors share diagnostic images through our XMPP platform, the system works like this: - **Clients negotiate** the exchange via XMPP (metadata visible to server) - The medical file transfers peer-to-peer or via HTTPS upload with a unique, secure link - The **messaging server never sees the actual content** – only the negotiation The regulation can only scan in-band messaging content and metadata, not the out-of-band transfers where sensitive material could actually reside. It will break confidentiality of legitimate medical discussions without accessing the data it claims to monitor. ### The open protocols impossibility Article 10.1's requirement to scan "prior to transmission" in end-to-end encrypted services assumes complete client control -- something impossible with open protocols like XMPP. The regulation demands that service providers guarantee scanning occurs before encryption on every client. But XMPP is a standardized, open protocol where anyone can develop compatible clients. On an average XMPP server, more than 30 different clients coexist. **How can we guarantee that each client respects scanning obligations when we cannot control their code?** The problem deepens with federation. XMPP servers interconnect, allowing users on different servers to exchange messages. When a message arrives from another server, it's already been end-to-end encrypted by a client we have no control over. There's no technical mechanism for the receiving server operator to enforce scanning requirements on clients that are not directly connected on its platform. This creates an absurd regulatory requirement: we would need to either abandon open standards entirely or somehow police every piece of software that implements XMPP, including modified open-source clients that users could easily deploy to bypass scanning. ## The circumvention reality Real criminals can easily bypass these measures through three complementary approaches that the regulation fails to address: **Distributed architecture:** Store content on external servers and share only URLs through chat, exactly what legitimate services like our XMPP platform already do naturally for file transfers. **External encryption:** Encrypt content with PGP, GnuPG, or OpenSSL before uploading it anywhere, making scanning meaningless regardless of the platform's capabilities. **Modified clients:** Use altered XMPP or Matrix clients that automatically implement these behaviors, exploiting the same open-source flexibility that makes compliance impossible. The result is predictable: **the regulation will only catch criminals amateur** **enough** to send illegal content directly as unencrypted attachments through unmodified clients. Meanwhile, it subjects all legitimate communications of European citizens to mass surveillance. This isn't theoretical speculation. These methods are already standard practice across European messaging infrastructure, used by both legitimate services and bad actors alike. ## The programmed death of European alternatives This regulation creates a structural disadvantage for European communication services trying to build alternatives to US tech giants. ### Complexity favors incumbents Annex XIV reveals a scoring system of Kafkaesque complexity, requiring considerable resources for compliance. This complexity structurally favors large platforms, usually Americans, that can: - Deploy massive financial resources to adapt their systems - Control their closed ecosystems completely - Distribute compliance costs across billions of users ### The decentralized ecosystem under threat Meanwhile, Europe's emerging decentralized alternatives face impossible technical requirements. There are currently tens of thousands of independent XMPP servers, federated Matrix deployments, and GDPR-compliant solutions that represent Europe's best chance for **digital messaging independence**. Can they comply with obligations designed around centralized architectures? We operate several messaging servers on behalf of customers. Under this regulation, we face a stark choice: shut down services we cannot control completely, from clients to servers, or force our European clients to migrate for example to Microsoft Teams to avoid regulatory complications. ## Conclusion This technical analysis reveals a regulation that fails on multiple levels. It demands **technical impossibilities** from European service providers while offering trivial workarounds for actual criminals. It structurally advantages US tech giants over European alternatives at precisely the moment Europe seeks digital independence. For communication service operators, this regulation creates an **impossible choice**: abandon open protocols and federated architectures that represent Europe's best path to messaging independence, or face legal risks with high mitigation costs even in lawful, legitimate use cases. The October 14th vote represents more than a policy choice about child protection. It's a decision about whether Europe will cripple its own communication infrastructure in pursuit of surveillance capabilities that won't work as promised. The current compromise proposal has been shared here: [Proposal for a Regulation of the European Parliament and of the Council laying down rules to prevent and combat child sexual abuse - Presidency compromise texts](https://cdn.netzpolitik.org/wp-upload/2025/07/2025-07-24%5FCouncil%5FPresidency%5FLEWP%5FCSA-R%5FCompromise-texts%5F11596.pdf?ref=process-one.net). This seems is the most up to date version of the text I could find. Read the text and make your own assessment of whether Europe can afford to implement technical requirements that its own industry cannot comply with. ### Spotify’s Direct Messaging Gambit URL: https://www.process-one.net/blog/spotifys-direct-messaging-gambit/ Last updated: 2025-09-11T12:09:38.000Z Last week, Spotify quietly launched direct messaging across its platform in selected areas, allowing users to share tracks and playlists through private conversations within the app. The feature was rolled out with minimal fanfare but significant media coverage, positioning itself as a complement to existing sharing mechanisms through Facebook, WhatsApp, and TikTok. When I read this, I immediately wondered why they were bothering. We do not especially lack communication channels these days. So, Let’s take a step back and examine what Spotify is actually trying to accomplish here. ## The Strange Case of Another Messaging App We already have too many messaging apps to choose, either on mobile or mobile phones. Before I try to initiate a conversation with someone I do not often chat with, I find myself trying to remember what is her preferred messaging platform. So, adding to an app some sorts of real time messaging and live interaction features can bring value, but it has to serve a purpose and respond to some user needs. In that context, Spotify’s decision to roll out direct messaging support feels odd. Users can already share music through established platforms where their friends actually are. They can post discoveries on social media, send links through WhatsApp, or create collaborative playlists. Why would anyone choose to message someone specifically within Spotify when they’re already connected elsewhere? The problem is that Spotify failed to make a compelling argument for why users should discuss with friends through yet another messaging system, even if this is to talk about music. Launching a special purpose communication service is risky. When Apple Music attempted to build Ping, a social network of music fans, it failed spectacularly. Spotify’s own social experiments haven’t fared much better. Remember Greenroom, their audio-focused social platform that quietly disappeared? This initiative becomes even more puzzling when we consider Spotify’s own history. The company built its initial viral growth through Facebook integration, leveraging social connections to drive adoption. And now, seemingly, they are trying to reclaim that social layer for themselves? ## What’s Really Happening Under the Hood The technical implementation reveals interesting choices. According to available reports, the messaging system relies on a RESTful API over HTTPS with TLS 1.3 encryption and JSON Web Tokens for session authentication. Notably absent? End-to-end encryption. And this absence tells us that the feature is not considered as a standard messaging service yet, but simply an alternative way to share favorite tracks and discuss them, and a possible a move to reduce the amount of data exposed to other social networks and messaging. ## The Data Intelligence Play Messaging features can provide enormous value when you have a strong daily user base, but only when they address a clear user need. Spotify’s messaging doesn’t seem designed for users. It feels designed for Spotify’s recommendation algorithms. Every shared track, every reaction, every conversation thread becomes a new data point in Spotify’s machine learning models. Who shares what with whom? Which songs generate discussion? How do musical tastes spread through social networks? This intelligence is pure gold for a recommendation engine that already struggles to compete with YouTube Music’s discovery capabilities. Private messaging amplifies this data collection while keeping the intelligence proprietary, unlike public social sharing, where competitors might also benefit. ## Strategic Confusion or Calculated Move? So, is this really all about data collection and control? This is where Spotify’s European identity becomes relevant. As a Swedish company competing against American tech giants, there may be strategic value in reducing dependence on US or controlled Chinese social platforms. Every track shared through WhatsApp (Meta) or TikTok (ByteDance) represents data flowing to potential competitors or partners with their own agenda. Building an internal messaging system allows Spotify to capture that social intelligence directly while reducing what they share with other platforms. From a data sovereignty perspective, this makes sense, especially for a European player navigating an increasingly fragmented global tech landscape. And they may hope at some point to play a larger role in messaging platforms in general, as we deeply miss a large player in the messaging field in Europe. It may be a play to test the waters. As we help companies reclaim their independence by building their own messaging service, this goal resonates strongly with us. However, building a successful messaging platform requires being able to create momentum around the service if it wants to attract enough users and traffic. It cannot be launched halfheartedly. ## The Missing Strategic Vision The fundamental problem isn’t technical. It’s strategic clarity. Spotify has a recommendation engine that could benefit from social signals, a creator platform focused on podcasts and videos, and a user base that already shares music socially. The ingredients for a compelling set of social features exist. But launching messaging without addressing the basic question of “Why would I message someone here instead of where we already talk?” suggests a feature developed in isolation from user needs. It resembles the countless platform features that launch with media coverage but die quietly when adoption numbers disappoint. What would make this feature compelling? Integration with Spotify’s creator tools, perhaps allowing artists to connect directly with fans. Or collaborative listening live sessions where messaging enhances shared musical experiences. Or leveraging Spotify’s podcast ecosystem to enable discussion around episodes. Instead, we get generic messaging that competes with platforms where users’ friends actually are. ## So, what’s Spotify’s real goal? I see two possible options here: a *pessimistic* and a more *optimistic* one. Perhaps the most interesting aspect of this launch is what it reveals about Spotify’s growth concerns. A mature platform doesn’t typically add generic social features unless it’s worried about engagement metrics or looking for new growth vectors. They may want their users to spend more time in its interface, instead of most of the time, passively using that app through a player exposed as a widget in the mobile operating system. The timing suggests Spotify sees either limited growth ahead or a competitive threat that requires better user data. Given the AI revolution in music generation and the ongoing battles over royalty structures, capturing more nuanced data about user preferences and social music behavior could be crucial for maintaining relevance. But there’s a more optimistic reading: this could represent a European tech company trying to assert more independence from American social platforms. In a world where data is power, controlling your own social graph has strategic value. The execution, however, suggests Spotify hasn’t quite figured out how to articulate this vision to users. Until they do, this messaging feature risks joining the graveyard of platform additions that made sense to product managers but never found their audience. In a world already oversaturated with communication channels, every new messaging system needs to answer a simple question: Why here instead of everywhere else users are already talking? Spotify hasn’t answered that question yet. ### 🚀 ejabberd 25.08 URL: https://www.process-one.net/blog/ejabberd-25-08/ Last updated: 2025-09-11T12:11:22.000Z **Release Highlights:** This release includes the support for Hydra rooms in our Matrix gateway, which fixes high severity protocol vulnerabilities. - **[Improvements in Matrix gateway](#matrix)** - **[Fixed ACME in Erlang/OTP 28.0.2](#acme)** - **[New mod\_providers to serve XMPP Providers file](#mod%5Fproviders)** If you are upgrading from a previous version, there are no changes in SQL schemas, configuration, API commands or hooks. **Other contents:** - **[Improved Unicode support in configuration](#unicode)** - **[New option conversejs\_plugins to enable OMEMO](#conversejs)** - **[Easier erlang node name change with mnesia\_change](#mnesia%5Fchange)** - **[Colorized interactive log](#colorlog)** - **[Document API tags in modules](#modules-tags)** - **[Acknowledgments](#ack)** - **[Improvements in ejabberd Business Edition](#ebe)** - **[ChangeLog](#changelog)** - **[ejabberd 25.08 download & feedback](#download)** Below is a detailed breakdown of the improvements and enhancements: ## Improvements in Matrix gateway The ejabberd [Matrix gateway](https://www.process-one.net/blog/hello-from-the-other-side-matrix-xmpp-via-ejabberd-25-03/ "Hello from the other side: Matrix ↔ XMPP via ejabberd") now supports [Hydra rooms](https://matrix.org/blog/2025/08/project-hydra-improving-state-res/?ref=process-one.net "Project Hydra: Improving state resolution in Matrix") (Matrix room version 12). This fix some [high severity protocol vulnerabilities](https://matrix.org/blog/2025/07/security-predisclosure/?ref=process-one.net "Pre-disclosure: Upcoming coordinated security fix for all Matrix server implementations"). The state resolution has been partially rewritten in our gateway. A double percent (%%) is used for separating a matrix server from a room ID in JID with Hydra rooms. Other changes to the matrix gateway: - The new option `notary_servers` of `mod_matrix_gw` can now be used to set a list of notary servers. - Add `leave_timeout` option to `mod_matrix_gw` (#4386) - Don't send empty direct Matrix messages (thanks to snoopcatt) (#4420) ## Fixed ACME in Erlang/OTP 28.0.2 The [ejabberd 25.07 release notes](https://www.process-one.net/blog/ejabberd-25-07/) mentioned that Erlang/OTP 28.0.1 was not yet fully supported because there was a problem with ACME support. Good news! this problem with ACME is fixed and tested to work when using Erlang/OTP 28.0.2, the latest `p1_acme` library, and ejabberd 25.08. If you are playing with ejabberd and Erlang/OTP 28, please report any problem you find. If you are running ejabberd in production, better stick with Erlang/OTP 27.3, this is the one used in installers and container images. ## New mod\_providers to serve XMPP Providers file [mod\_providers](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fproviders) is a new module to serve easily [XMPP Providers](https://providers.xmpp.net/?ref=process-one.net) files. The standard way to perform this task is to first [generate the Provider File](https://providers.xmpp.net/provider-file-generator/?ref=process-one.net), store in the disk with the proper name, and then serve the file using an HTTP server or [mod\_http\_fileserver](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fhttp%5Ffileserver). And repeat this for each vhost. Now this can be replaced with mod\_providers, which automatically sets some values according to your configuration. Try configuring ejabberd like: ```yaml listen: - port: 443 module: ejabberd_http tls: true request_handlers: /.well-known/xmpp-provider-v2.json: mod_providers modules: mod_providers: {} ``` Check the URL `https://localhost:443/.well-known/xmpp-provider-v2.json`, and finetune it by setting a few [mod\_providers](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fproviders) options. ## Improved Unicode support in configuration When using non-latin characters in a vhost served by ejabberd, you can write it in the configuration file as unicode, or using the IDNA/punycode. For example: ```yaml hosts: - localhost1 - locälhost2 - xn--loclhost4-x2a - 日本語 host_config: "locälhost2": modules: mod_disco: {} mod_muc: host: "conference3.@HOST@" "xn--loclhost4-x2a": modules: mod_disco: {} mod_muc: host: "conference4.@HOST@" ``` This raises a problem in [mod\_http\_upload](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fhttp%5Fupload) if the option `put_url` contains the `@HOST@` keyword. In that case, please use the new [predefined keyword](https://docs.ejabberd.im/admin/configuration/file-format/?ref=process-one.net#predefined-keywords) `HOST_URL_ENCODE`. This change was also applied to `ejabberd.yml.example`. ## New option conversejs\_plugins to enable OMEMO [mod\_conversejs](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fconversejs) gets a new option `conversejs_plugins` that points to additional local files to include as scripts in the homepage. Right now this is useful to enable [OMEMO encryption](https://conversejs.org/docs/html/features.html?ref=process-one.net#end-to-end-message-encryption-xep-0384-omemo). Please make sure those files are available in the path specified in `conversejs_resources` option, in subdirectory `plugins/`. For example, copy a file to path `/home/ejabberd/conversejs-x.y.z/package/dist/plugins/libsignal-protocol.min.js` and then configure like: ```yaml modules: mod_conversejs: conversejs_resources: "/home/ejabberd/conversejs-x.y.z/package/dist" conversejs_plugins: ["libsignal-protocol.min.js"] ``` If you are using the public Converse client, then you can set `"libsignal"`, which gets replaced with the URL of the public library. For example: ```yaml modules: mod_conversejs: conversejs_plugins: ["libsignal"] websocket_url: "ws://@HOST@:5280/websocket" ``` ## Easier erlang node name change with mnesia\_change ejabberd uses by default the distributed Mnesia database. Being distributed, Mnesia enforces consistency of its file, so it stores the Erlang node name, which may include the hostname of the computer. When the erlang node name changes (which may happen when changing the computer name, or moving ejabberd to another computer), then mnesia refused to start with an error message like this: ``` 2025-08-21 11:06:31.831594+02:00 [critical] Erlang node name mismatch: I'm running in node [ejabberd2@localhost], but the mnesia database is owned by [ejabberd@localhost] 2025-08-21 11:06:31.831782+02:00 [critical] Either set ERLANG_NODE in ejabberdctl.cfg or change node name in Mnesia ``` To change the computer hostname in the mnesia database, it was required to follow a [tutorial with 10 steps](https://docs.ejabberd.im/admin/guide/managing/?ref=process-one.net#change-computer-hostname) that starts ejabberd a pair of times and runs the [mnesia\_change\_nodename](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#mnesia%5Fchange%5Fnodename) API command. Well, now all this tutorial is implemented in one single command for the `ejabberdctl` command line script. When mnesia refuses to start due to an erlang node name change, it mentions that new solution: ``` $ echo "ERLANG_NODE=ejabberd2@localhost" >>_build/relive/conf/ejabberdctl.cfg $ ejabberdctl live 2025-08-21 11:06:31.831594+02:00 [critical] Erlang node name mismatch: I'm running in node [ejabberd2@localhost], but the mnesia database is owned by [ejabberd@localhost] 2025-08-21 11:06:31.831782+02:00 [critical] Either set ERLANG_NODE in ejabberdctl.cfg or change node name in Mnesia by running: ejabberdctl mnesia_change ejabberd@localhost ``` Let's use the new command to change the erlang node name stored in the mnesia database: ```shell $ ejabberdctl mnesia_change ejabberd@localhost ==> This changes your mnesia database from node name 'ejabberd@localhost' to 'ejabberd2@localhost' ... ==> Finished, now you can start ejabberd normally ``` Great! Now ejabberd can start correctly: ```shell $ ejabberdctl live ... 2025-08-21 11:18:52.154718+02:00 [info] ejabberd 25.07.51 is started in the node ejabberd2@localhost in 1.77s ``` Notice that the command `mnesia_change` must start and stop ejabberd a pair of times. For that reason, it cannot be implemented as an [API command](https://docs.ejabberd.im/developer/ejabberd-api/?ref=process-one.net). Instead, it is implemented as an [ejabberdctl command](https://docs.ejabberd.im/admin/guide/managing/?ref=process-one.net#ejabberdctl-commands) directly in the [ejabberdctl](https://docs.ejabberd.im/admin/guide/managing/?ref=process-one.net#ejabberdctl) command line script. ## Colorized interactive log When ejabberd starts with an erlang shell using Mix, it prints error lines in a remarkable color: orange for warnings and red for errors. This helps to detect those lines when reading the log interactively. Now this is also supported when using Rebar3\. To test it, start ejabberd either: - `ejabberdctl live`: to start interactive mode with erlang shell - `ejabberdctl foreground`: to start in server mode with attached log output You will see log lines colorized with: - green+white for informative log messages - grey for debug - yellow for warnings - red for errors - magenta for messages coming from other Erlang libraries (xmpp, OTP library), not ejabberd itself ## Document API Tags in modules Many [ejabberd modules](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net) implement their own [API commands](https://docs.ejabberd.im/developer/ejabberd-api/?ref=process-one.net), and now the documentation of those modules mention which tags contain their commands. See for example at the end of modules [mod\_muc\_admin](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmuc%5Fadmin), [mod\_private](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fprivate) or [mod\_antispam](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fantispam). Unfortunately, many early API commands were implemented in [mod\_admin\_extra](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fadmin%5Fextra), which includes commands related to account management, vcard, roster, private, ... and consequently those are not mentioned in their corresponding modules documentation. ## Acknowledgments We would like to thank the contributions to the source code provided for this release by: - mod\_matrix\_gw: Don't send empty direct Matrix messages (thanks to snoopcatt) (#4420) - [Holger Weiß](https://github.com/weiss?ref=process-one.net) for improvements in the installers, HTTP file upload and mod\_register - [marc0s](https://github.com/marc0s?ref=process-one.net) for the improvement in MUC And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get the following changes: ### New module `mod_dedup` This module removes duplicates of read receipts sent by concurrent sessions of single user, this will prevent both delivery and storage in archive of duplicates. ### Limits in `mod_unread` queries Queries issued to `mod_unread` can now declare maximum number and age of returned results. This can also be tweaked with new options of that module. ## ChangeLog This is a more complete list of changes in this ejabberd release: #### API Commands - `ban_account`: Run `sm_kick_user` event when kicking account ([#4415](https://github.com/processone/ejabberd/issues/4415?ref=process-one.net)) - `ban_account`: No need to change password ([#4415](https://github.com/processone/ejabberd/issues/4415?ref=process-one.net)) - `mnesia_change`: New command in `ejabberdctl` script that helps changing the mnesia node name #### Configuration - Rename `auth_password_types_hidden_in_scram1` option to `auth_password_types_hidden_in_sasl1` - `econf`: If a host in configuration is encoded IDNA, decode it ([#3519](https://github.com/processone/ejabberd/issues/3519?ref=process-one.net)) - `ejabberd_config`: New predefined keyword `HOST_URL_ENCODE` - `ejabberd.yml.example`: Use `HOST_URL_ENCODE` to handle case when vhost is non-latin1 - `mod_conversejs`: Add option `conversejs_plugins` ([#4413](https://github.com/processone/ejabberd/issues/4413?ref=process-one.net)) - `mod_matrix_gw`: Add `leave_timeout` option ([#4386](https://github.com/processone/ejabberd/issues/4386?ref=process-one.net)) #### Documentation and Tests - `COMPILE.md`: Mention dependencies and add link to Docs ([#4431](https://github.com/processone/ejabberd/issues/4431?ref=process-one.net)) - `ejabberd_doc`: Document commands tags for modules - CI: bump XMPP-Interop-Testing/xmpp-interop-tests-action ([#4425](https://github.com/processone/ejabberd/issues/4425?ref=process-one.net)) - Runtime: Raise the minimum Erlang tested to Erlang/OTP 24 #### Installers and Container - Bump Erlang/OTP version to 27.3.4.2 - Bump OpenSSL version to 3.5.2 - `make-binaries`: Disable Linux-PAM's `logind` support #### Core and Modules - Bump `p1_acme` to fix `'AttributePKCS-10'` and OTP 28 ([processone/p1\_acme#4](https://github.com/processone/p1%5Facme/issues/4?ref=process-one.net)) - Prevent loops in `xml_compress:decode` with corrupted data - `ejabberd_auth_mnesia`: Fix issue with filtering duplicates in `get_users()` - `ejabberd_listener`: Add secret in temporary unix domain socket path ([#4422](https://github.com/processone/ejabberd/issues/4422?ref=process-one.net)) - `ejabberd_listener`: Log error when cannot set definitive unix socket ([#4422](https://github.com/processone/ejabberd/issues/4422?ref=process-one.net)) - `ejabberd_listener`: Try to create provisional socket in final directory ([#4422](https://github.com/processone/ejabberd/issues/4422?ref=process-one.net)) - `ejabberd_logger`: Print log lines colorized in console when using rebar3 - `mod_conversejs`: Ensure assets\_path ends in `/` as required by Converse ([#4414](https://github.com/processone/ejabberd/issues/4414?ref=process-one.net)) - `mod_conversejs`: Ensure plugins URL is separated with `/` ([#4413](https://github.com/processone/ejabberd/issues/4413?ref=process-one.net)) - `mod_http_upload`: Encode URLs into IDNA when showing to XMPP client ([#3519](https://github.com/processone/ejabberd/issues/3519?ref=process-one.net)) - `mod_matrix_gw`: Add support for null values in `is_canonical_json` ([#4421](https://github.com/processone/ejabberd/issues/4421?ref=process-one.net)) - `mod_matrix_gw`: Don't send empty direct Matrix messages ([#4420](https://github.com/processone/ejabberd/issues/4420?ref=process-one.net)) - `mod_matrix_gw`: Matrix gateway updates - `mod_muc`: Report db failures when restoring rooms - `mod_muc`: Unsubscribe users from members-only rooms when expelled ([#4412](https://github.com/processone/ejabberd/issues/4412?ref=process-one.net)) - `mod_providers`: New module to serve easily XMPP Providers files - `mod_register`: Don't duplicate welcome subject and message - `mod_scram_upgrade`: Fix format of passwords updates - `mod_scram_upgrade`: Only offer upgrades to methods that aren't already stored ### Full Changelog [https://github.com/processone/ejabberd/compare/25.07...25.08](https://github.com/processone/ejabberd/compare/25.07...25.08?ref=process-one.net) ## ejabberd 25.08 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### XMPP: When a 25-Year-Old Protocol Becomes Strategic Again URL: https://www.process-one.net/blog/xmpp-when-a-25-year-old-protocol-becomes-strategic-again/ Last updated: 2025-07-24T14:33:44.000Z After twenty-five years, [**XMPP**](https://xmpp.org/?ref=process-one.net) (Extensible Messaging and Presence Protocol) is still here. Mature, proven, modular, and standardized, it may well be **the most solid foundation available today** to build the future of messaging. And now, XMPP is more relevant than ever: its resurgence is driven by European digital sovereignty efforts, renewed focus on interoperability, and the growing need for long-term, vendor-independent infrastructure. Against this backdrop, the recent funding round around [**XMTP**](https://xmtp.org/?ref=process-one.net) **(Extensible Message Transport Protocol)**, a newly launched blockchain-based protocol marketed as a universal messaging layer, raises questions. The name clearly evokes XMPP, yet there is no technological or community connection. And while XMPP could easily serve as a transport layer for blockchain-integrated messaging, **XMTP chooses to ignore this legacy and start anew**. So the real question is: **Why rebuild from scratch when a solid, extensible foundation already exists?** ## A Protocol That Never Went Away XMPP is an open protocol for real-time messaging, designed from the start for federation and decentralization. Standardized by the IETF (RFC 6120, 6121, 7622…), it has powered mission-critical systems for decades: enterprise communication, mobile apps at scale, online games, IoT control platforms. What makes XMPP especially powerful is not just its architectural simplicity, but its **modular extensibility**. The protocol evolves through an ecosystem of open specifications (XEPs), covering: - End-to-end encryption (OMEMO, OTR) - Multi-device synchronization (Message Archive Management) - Group chat with subscriptions (MUC and MUCSub) - PubSub (XEP-0060) for real-time data and events - Interoperability bridges (SIP, MQTT, Matrix) - And more… XMPP **has never stopped evolving**. Dozens of new extensions are proposed every year. It remains one of the most adaptable foundations for building secure, federated, and future-ready messaging systems. ## XMTP: A New Protocol with a Familiar Name, but a Different Approach XMTP is a blockchain-native messaging protocol developed by Ephemera. It aims to connect wallets and dApps, leveraging decentralized infrastructure (libp2p, IPFS-style storage) and cryptographic identities. The ambition is clear: to build a censorship-resistant, peer-to-peer messaging layer for Web3, rooted in crypto-native identity and cryptography. However, the naming is misleading. In an [older interview](https://web3galaxybrain.com/episode/XMTP-with-Matt-Galligan?ref=process-one.net), XMTP co-founder Matt Galligan said the name is a blend of SMTP and XMPP. It was chosen to evoke familiarity, perhaps even as a tribute. But **the result is confusing**: XMTP is not an extension, evolution, or even distant cousin of XMPP. There is no shared architecture, no interoperability, no community overlap. ## Why This Matters Right Now This naming issue would be minor if it weren’t happening at a **critical time for protocol design**. Governments, especially in Europe, are actively exploring how to regain control over digital infrastructure. Messaging is central to this effort, especially with upcoming interoperability mandates, data sovereignty requirements, and the need for long-term maintainability. **XMPP is uniquely well-positioned** to meet these needs. It is mature, open, extensible, and governed through transparent standards. It has a community of engineers, operators, and developers actively maintaining and evolving it. Instead of inventing closed messaging stacks around new ecosystems, the more pragmatic move would be to **build on robust, extensible layers like XMPP**: - Need to integrate blockchain identities? XMPP can map public keys or wallet identifiers through custom namespaces or JIDs. - Need cryptographic message-level guarantees? XMPP already supports message metadata, signatures, and encryption. - Need better privacy ? XMPP can be run over privacy-preserving transports like Tor. In short: **XMPP can serve as a transport layer for Web3 communication** without discarding two decades of protocol maturity. I understand that the main focus of XMTP is to prevent censorship, but this really a situation that can be mitigated efficiently with XMPP. You can for example run your own server or develop a fully decentralized approach that you can leverage as needed (e.g. [xmpp-overlay](https://github.com/USNavalResearchLaboratory/xmpp-overlay?ref=process-one.net)). Yes, there is still work to be done. For example, integrating **MLS (Messaging Layer Security)** into XMPP would provide a strong foundation for interoperable, end-to-end encrypted group messaging. But that only reinforces the point: **Why ignore what’s already working and extensible?** ## Use What Works New ideas are always welcome. Innovation matters. But messaging protocols are infrastructure. Reinventing them lightly, is not harmless, especially when it is done without acknowledging existing efforts. Instead of multiplying disconnected stacks, we should **double down on what works**. **XMPP is here. It works. It evolves.** It can be extended, adapted, and integrated, even into blockchain-native systems, without sacrificing openness or interoperability. That may be its most valuable trait today: **Still standing, while so many overengineered protocols have come and gone.** ### ejabberd 25.07 URL: https://www.process-one.net/blog/ejabberd-25-07/ Last updated: 2025-07-24T18:39:22.000Z **Release Highlights:** This release focus on integration in a wider federated network, with support for spam fighting features, better compliance with Matrix network and native support for PubSub Server Information to have your server count as part of the wider XMPP network (for example, you can register your server on [XMPP Network Graph](https://xmppnetwork.goodbytes.im/?ref=process-one.net)). - **Spam filter with block lists support** - **Support for XEP-0485: PubSub Server Information** - **Support for older Matrix rooms in ejabberd XMPP <-> Matrix Gateway** If you are upgrading from a previous version, there are no changes in SQL schemas, configuration, API commands or hooks. **List of Contents:** - **Workaround for `zip` module in unpatched Erlang** - **Erlang/OTP 28 supported** - **Erlang/OTP 25 required** - **New `mod_antispam` with RTBL support** - **New** **`mod_pubsub_serverinfo`** - **Improvements in Matrix gateway** - **XEP-0431: Full Text Search in MAM** - **New `rest_proxy` options** - **New `auth_password_types_hidden_in_scram1` option** - **New `host_alias` option** - **New predefined keywords** - **Link to Converse in WebAdmin** - **Updates in source code formatting** - **New target `test-group`** - **Acknowledgments** - **Improvements in ejabberd Business Edition** - **ChangeLog** - **ejabberd 25.07 download & feedback** Below is a detailed breakdown of the improvements and enhancements: ## Workaround for `zip` module in unpatched Erlang A vulnerability was published three weeks ago that affects the `zip` library included in Erlang/OTP: [CVE-2025-4748: Absolute path in zip module](https://github.com/erlang/otp/security/advisories/GHSA-9g37-pgj9-wrhc?ref=process-one.net). The ejabberd [installers](https://docs.ejabberd.im/admin/install/binary-installer/?ref=process-one.net) and the `ejabberd` [container](https://docs.ejabberd.im/CONTAINER/?ref=process-one.net) image already use a patched version Erlang/OTP 27.3.4.1, but the `ecs` [container](https://docs.ejabberd.im/CONTAINER/?ref=process-one.net) image uses Erlang/OTP 26.2. ejabberd 25.07 includes a specific protection that workarounds that vulnerability regardless of what Erlang/OTP version you are using. ## Erlang/OTP 28 supported Updating ejabberd to support Erlang/OTP 28 has required quite some work due to the [replacement of ancient ASN.1 modules](https://www.erlang.org/doc/apps/public%5Fkey/notes.html?ref=process-one.net#public%5Fkey-1-18) from Erlang/OTP `public_key` library. Improvements were done on ejabberd, `fast_xml`, `p1_acme`, `xmpp` libraries, and also `rebar`/`rebar3` binaries were recompiled. However, there is still [one last problem](https://github.com/processone/p1%5Facme/issues/4?ref=process-one.net) not yet solved which implies that ACME support is broken when using Erlang/OTP 28.0.1\. The fix will probably be included in the next Erlang/OTP 28 release. ## Erlang/OTP 25 required The minimum Erlang/OTP version supported since now is 25.0. However, we are aware there are still a few specific cases where older Erlang/OTP versions are being used. For that reason, the source code support for those versions is still available, and static source code analysis tools like `xref` and `dialyzer` are still run with Erlang/OTP 20 in `runtime.yml`. If you really need to use ejabberd with Erlang/OTP 20 - 24, you can bypass the version check during compilation with this [./configure](https://docs.ejabberd.im/admin/install/source/?ref=process-one.net#configure) option: `./configure --with-min-erlang=9.0.5` ## New `mod_antispam` with RTBL support [mod\_antispam](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fantispam) is a new module that filters spam messages and subscription requests received from remote servers based on [Real-Time Block Lists (RTBL)](https://xmppbl.org/?ref=process-one.net), text lists of known spammer JIDs and/or URLs mentioned in spam messages. This module is based in [mod\_spam\_filter](https://github.com/processone/ejabberd-contrib/tree/master/mod%5Fspam%5Ffilter?ref=process-one.net) which was originally published in [ejabberd-contrib](https://docs.ejabberd.im/admin/guide/modules/?ref=process-one.net#ejabberd-contrib). If you were using that module, you can update your configuration and start using `mod_antispam` instead. ## New `mod_pubsub_serverinfo` [mod\_pubsub\_serverinfo](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fpubsub%5Fserverinfo) adds support for [XEP-0485: PubSub Server Information](https://xmpp.org/extensions/xep-0485.html?ref=process-one.net) to expose S2S information over the Pub/Sub service. This module was [originally published](https://github.com/processone/ejabberd-contrib/tree/master/mod%5Fpubsub%5Fserverinfo?ref=process-one.net) in [ejabberd-contrib](https://docs.ejabberd.im/admin/guide/modules/?ref=process-one.net#ejabberd-contrib). If you were using that module, you can remove it, as now it's included in ejabberd. ## Improvements in Matrix gateway While we are preparing another big update for the Matrix gateway. The most important change is that we added support to a larger number of room versions. It allows users to let them join a lot of rooms that were already created a while back and running an older version of the room protocol. Here is the main list of changes to the matrix gateway: - `mod_matrix_gw`: Support older Matrix rooms versions starting from version 4 - `mod_matrix_gw`: Don't send empty messages in Matrix rooms (#4385) - `mod_matrix_gw`: Fix key validation in mod\_matrix\_gw\_s2s:check\_signature - `mod_matrix_gw`: When encoding JSON, handle term that is key-value list (#4379) ## XEP-0431: Full Text Search in MAM Support for [XEP-0431: Full Text Search in MAM](https://xmpp.org/extensions/xep-0431.html?ref=process-one.net) has been added. For now, it only works if [mod\_mam](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmam) is using the MySQL storage backend. ## New `rest_proxy` options With those new options you can make modules using `rest.erl `module (like `ejabberd_oauth_rest`) use HTTP proxy when performing HTTP requests. The related new [top level options](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#rest%5Fproxy) are: - `rest_proxy`: Address of a HTTP Connect proxy - `rest_proxy_port`: Port of a HTTP Connect proxy - `rest_proxy_username`: Username used to authenticate to HTTP Connect proxy (optional) - `rest_proxy_password`: Password used to authenticate to HTTP Connect proxy (optional) ## New `auth_password_types_hidden_in_scram1` option This option was added to help with adding new password types in `auth_stored_password_types` option to existing installations. Adding new password type made server advertise it to clients, but that caused problems for users that didn't have new password type stored, and which clients used SASL1 authentication, if client tried to authenticate with it, authentications would fail. With this new option, server admin can choose which password types should not be presented to SASL1 clients (they still will be offered to SASL2 clients for users that have password compatible with this type), to later after users update password to have new type, being able to enable them. This option takes list of password types from `auth_stored_password_types` that should be disabled ```yaml auth_password_types_hidden_in_scram1: - scram_sha512 - scram_sha256 ``` ## New `hosts_alias` option The new [hosts\_alias](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#hosts%5Falias) toplevel option is used by the [ejabberd\_http](https://docs.ejabberd.im/admin/configuration/listen/?ref=process-one.net#ejabberd%5Fhttp) listener to resolve domain names into vhosts served by ejabberd. For example, ejabberd is serving the vhost `redacted.lan`, but you configured DNS so `xmpp.redacted.lan` resolves to that host. If you configure in ejabberd: ```yaml hosts: - redacted.lan hosts_alias: xmpp.redacted.lan: redacted.lan listen: - port: 443 ip: "::" tls: true module: ejabberd_http request_handlers: "/bosh": mod_bosh "/ws": ejabberd_http_ws "/conversejs": mod_conversejs modules: mod_bosh: mod_conversejs: bosh_service_url: "https://xmpp.redacted.lan/bosh" websocket_url: "wss://xmpp.redacted.lan/ws" ``` then `ejabberd_http` will accept `https://xmpp.redacted.lan/conversejs` and deliver it to vhost `redacted.lan` In previous ejabberd releases, an option called [default\_host](https://docs.ejabberd.im/archive/24.10/listen-options/?ref=process-one.net#default%5Fhost) was documented for the `ejabberd_http` listener, but it didn't work at all correctly. ## New predefined keywords A few months ago, [ejabberd 25.03 introduced](https://www.process-one.net/blog/ejabberd-25-03/#a-namekeyworda-macros-and-keyword-improvements) new [predefined keywords](https://docs.ejabberd.im/admin/configuration/file-format/?ref=process-one.net#predefined-keywords) like `HOST`, `HOME`, `VERSION` and `SEMVER`. And now two more predefined keywords are added: - `CONFIG_PATH`: Path to the configuration directory, for example `"/home/ejabberd/opt/ejabberd/conf"` - `LOG_PATH`: Path to the [log](https://docs.ejabberd.im/admin/configuration/basic/?ref=process-one.net#logging) directory, for example `"/home/ejabberd/opt/ejabberd/logs"` Those keywords are specially useful when configuring `mod_antispam`: you can copy text files to the configuration directory where the module will read them, and also configure the module to write the dump file on the log directory. ## Link to Converse in WebAdmin [mod\_conversejs](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fconversejs) has a new tiny improvement: it adds a link in the [WebAdmin](https://docs.ejabberd.im/admin/guide/managing/?ref=process-one.net#web-admin) menu to the local Converse instance. Additionally, when HTTPS with encryption is enabled, that link logins directly with the account used in WebAdmin. ## Updates in source code formatting A year ago, [ejabberd 24.06 introduced](https://www.process-one.net/blog/ejabberd-24-06/#experimental-make-format-and-indent) `make format` and `make indent`. Now that script uses Perl to work correctly in Mac OS too. And there's a new section in the documentation, see [Format](https://docs.ejabberd.im/developer/guide/?ref=process-one.net#format) that describes how to use that feature, and tips for Git hooks and Git alias. ## New target `test-group` ejabberd includes a [Common Test](https://www.erlang.org/doc/apps/common%5Ftest/introduction.html?ref=process-one.net) suite with 1456 test cases, which typically takes around 10 minutes to run. When developing new source code, you may want to run only tests from a specific group and a specific storage backend, as documented in the [ejabberd testing documentation](https://docs.ejabberd.im/developer/extending-ejabberd/testing/?ref=process-one.net): ```bash CT_BACKENDS=mnesia rebar3 ct --suite=test/ejabberd_SUITE --group=antispam_single ``` To facilitate this usage, a new target is available: ```bash CT_BACKENDS=mnesia make test-antispam_single ``` ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) and [Holger Weiß](https://github.com/weiss?ref=process-one.net) for `mod_antispam` and the original `mod_spam_filter` - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for `mod_pubsub_serverinfo` and `test-group` target - [Bruno MATEU](https://github.com/Britaliope?ref=process-one.net) for the missing comma in postgres schema - [GiannosOB](https://github.com/GiannosOB?ref=process-one.net) updated the Greek translation - [Tamil Neram](https://github.com/TamilNeram?ref=process-one.net) updated the Tamil translation - [Максим Горпиніч](https://hosted.weblate.org/user/maksimgorpinic2005a/?ref=process-one.net) updated the Ukrainian translation And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get the following changes. ### Monitoring The following new metrics has been added to `mod_mon`: - `message_receive_packet`: number of message stanzas of any type received by the server on c2s connections - `message_send_packet`: number of message stanzas of any type send by the server on c2s connections - `iq_receive_packet`: number of IQ stanzas received by the server on c2s connections - `iq_send_packet`: number of IQ stanzas send by the server on c2s connections - `iq_get_receive_packet`: number of IQ stanzas of type `get` received by the server on c2s connections - `iq_set_receive_packet`: number of IQ stanzas of type `set` received by the server on c2s connections - `iq_result_receive_packet`: number of IQ stanzas of type `result` received by the server on c2s connections - `iq_error_receive_packet`: number of IQ stanzas of type `error` received by the server on c2s connections - `iq_get_send_packet`: number of IQ stanzas of type `get` send by the server on c2s connections - `iq_set_send_packet`: number of IQ stanzas of type `set` send by the server on c2s connections - `iq_result_send_packet`: number of IQ stanzas of type `result` send by the server on c2s connections - `iq_error_send_packet`: number of IQ stanzas of type `error` send by the server on c2s connections The metrics `c2s_receive` & `c2s_send` now count all stanzas on c2s connections. The `cpu_usage` probe now gives more reliable values. [Prometheus](https://prometheus.io/?ref=process-one.net) support has been improved. A new `mod_mon_dump` command has been added to dump probe values to help debug the monitoring setup.r ### Mobile push It is now possible to use `rest_proxy*` options to use a HTTP proxy for `mod_applepush` & `mod_gcm` outgoing calls. ## ChangeLog This is a more complete list of changes in this ejabberd release: #### Security fix - `ext_mod`: Add temporary workaround for zip including absolute path #### Compilation - Raise the minimum Elixir tested version to 1.14.0 ([#4281](https://github.com/processone/ejabberd/issues/4281?ref=process-one.net)) - Raise Erlang/OTP minimum requirement to 25.0 ([#4281](https://github.com/processone/ejabberd/issues/4281?ref=process-one.net)) - `configure.ac`: Allow to specify minimal erlang version using `--with-min-erlang` - `Makefile.in`: Add target `test-` - `rebar3-format.sh`: Replace csplit with perl - Container: Bump Erlang/OTP 27.3.4.1, Elixir 1.18.4 - Installers: Bump Erlang/OTP 27.3.4.1, Elixir 1.18.4, libexpat 2.7.1, OpenSSL 3.5.1 #### Configuration and Tests - Add `rest_proxy*` options to configure proxy used by rest module - `ejabberd_c2s`: Add `auth_password_types_hidden_in_scram1` option - `ejabberd_http`: Remove unused `default_host` option and state element - `ejabberd_http`: New option `hosts_alias` and function `resolve_host_alias/1` ([#4400](https://github.com/processone/ejabberd/issues/4400?ref=process-one.net)) - New predefined keywords: `CONFIG_PATH` and `LOG_PATH` - Fix macro used in string options when defined in env var - Use auxiliary function to get `$HOME`, use Mnesia directory when not set ([#4402](https://github.com/processone/ejabberd/issues/4402?ref=process-one.net)) - `ejabberd_config`: Better `lists:uniq` substitute - Tests: update readme and compose to work with current sw versions - Update Elvis to 4.1.1, fix some warnings and enable their tests #### Erlang/OTP 28 support - Add workaround in `p1_acme` for Jose 1.11.10 not supporting OTP 28 `ecPrivkeyVer1` ([#4393](https://github.com/processone/ejabberd/issues/4393?ref=process-one.net)) - Bump `fast_xml` and `xmpp` for improved Erlang/OTP 28 support - Bump `xmpp` and `p1_acme` patched with Erlang/OTP 28 support - Fix `make options` in Erlang/OTP 28 ([#4352](https://github.com/processone/ejabberd/issues/4352?ref=process-one.net)) - Fix crash in `rebar3 cover` with Erlang/OTP 28 ([#4353](https://github.com/processone/ejabberd/issues/4353?ref=process-one.net)) - Rebar/Rebar3: Update binaries to work with Erlang/OTP 25-28 ([#4354](https://github.com/processone/ejabberd/issues/4354?ref=process-one.net)) - CI and Runtime: Add Erlang/OTP 28 to the versions matrix #### SQL - Fix mnesia to sql exporter after changes to auth tables - Update code for switching to new schema type to users table changes - Add mssql specific implementation of `delete_old_mam_messages` - Make `delete_old_mam_messages_batch` work with sqlite - `ejabberd_sm_sql`: Use misc:encode\_pid/1 - `mysql.sql`: Fix typo in commit 7862c6a when creating users table - `pg.sql`: Fix missing comma in postgres schema ([#4409](https://github.com/processone/ejabberd/issues/4409?ref=process-one.net)) #### Core and Modules - `ejabberd_s2s_in`: Allow S2S connections to accept client certificates that have only server purpose ([#4392](https://github.com/processone/ejabberd/issues/4392?ref=process-one.net)) - `ext_mod`: Recommend to write README.md instead txt (processone/ejabberd-contrib#363) - `ext_mod`: Support library path installed from Debian (processone/ejabberd-contrib#363) - `ext_mod`: When upgrading module, clean also the compiled directories - `gen_mod`: Add support to prepare module stopping before actually stopping any module - `mod_antispam`: Imported from ejabberd-contrib and improved ([#4373](https://github.com/processone/ejabberd/issues/4373?ref=process-one.net)) - `mod_auth_fast`: Clear tokens on kick, change pass and unregister ([#4397](https://github.com/processone/ejabberd/issues/4397?ref=process-one.net))([#4398](https://github.com/processone/ejabberd/issues/4398?ref=process-one.net))([#4399](https://github.com/processone/ejabberd/issues/4399?ref=process-one.net)) - `mod_conversejs`: Add link in WebAdmin to local Converse if configured - `mod_mam`: Present mam full text search in xep-431 compatible way - `mod_mam_mnesia`: Handle objects that don't need conversion in `transform/0` - `mod_matrix_gw`: Don't send empty messages in Matrix rooms ([#4385](https://github.com/processone/ejabberd/issues/4385?ref=process-one.net)) - `mod_matrix_gw`: Support older Matrix rooms versions starting from version 4 - `mod_matrix_gw`: When encoding JSON, handle term that is key-value list ([#4379](https://github.com/processone/ejabberd/issues/4379?ref=process-one.net)) - `mod_matrix_gw_s2s`: Fix key validation in `check_signature` - `mod_mix` and `mod_muc_rtbl`: Support list of IDs in `pubsub-items-retract` (processone/xmpp#100) - `mod_pubsub_serverinfo`: Imported module from ejabberd-contrib ([#4408](https://github.com/processone/ejabberd/issues/4408?ref=process-one.net)) - `mod_register`: Normalize username when determining if user want to change pass - `mod_register`: Strip query data when returning errors - WebAdmin: New hooks `webadmin_menu_system` to add items to system menu ### Full Changelog [https://github.com/processone/ejabberd/compare/25.04...25.07](https://github.com/processone/ejabberd/compare/25.04...25.07?ref=process-one.net) ## ejabberd 25.07 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### ejabberd 25.04 URL: https://www.process-one.net/blog/ejabberd-25-04/ Last updated: 2025-04-16T17:21:45.000Z Just a few weeks after previous release, ejabberd 25.04 is published with an important security fix, several bug fixes and a new API command. **Release Highlights:** - **[Fix handling multiple occupant-id](#occupantid)** - **[Kick\_users API command](#kickusers)** If you are upgrading from a previous version, there are no changes in SQL schemas, configuration, API commands or hooks. **Other contents:** - **[Acknowledgments](#ack)** - **[Improvements in ejabberd Business Edition](#ebe)** - **[ChangeLog](#changelog)** - **[ejabberd 25.04 download & feedback](#download)** Below is a detailed breakdown of the improvements and enhancements: ## mod\_muc\_occupantid: Fix handling multiple occupant-id Fixed issue with handling of user provided occupant-id in messages and presences sent to muc room. Server was replacing just first instance of occupant-id with its own version, leaving other ones untouched. That would mean that depending on order in which clients send occupant-id, they could see value provided by sender, and that could be used to spoof as different sender. ## New kick\_users API command There is a new API command [kick\_users](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#kick%5Fusers) that disconnects all the client sessions in a given virtual host. ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Travis Burtrum](https://github.com/moparisthebest?ref=process-one.net) for reporting problem in occupant-id - [Marcos de Vera Piquero](https://github.com/marc0s?ref=process-one.net) for the new `kick_users` API command - [Besnik Bleta](https://github.com/ujdhesa?ref=process-one.net), updated the Albanian translation - [Sketch6580](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net), updated the Chinese translation - [Nautilusx](https://hosted.weblate.org/user/nautilusx/?ref=process-one.net), updated the German translation - [Silvério Santos](https://github.com/SantosSi?ref=process-one.net), updated the Portuguese translation - [Wellington Uemura](https://github.com/wtuemura?ref=process-one.net), updated the Portuguese (Brazil) translation - [Максим Горпиніч](https://hosted.weblate.org/user/maksimgorpinic2005a/?ref=process-one.net), updated the Ukrainian translation And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition For customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes: - Bugfix on `max_concurrent_connections` for `mod_gcm`, `mod_webhook` and `mod_webpush` ## ChangeLog This is a more complete list of changes in this ejabberd release: #### Security fixes - `mod_muc_occupantid`: Fix handling multiple occupant-id #### Commands API - `kick_users`: New command to kick all logged users for a given host #### Bugfixes - Fix issue with sql schema auto upgrade when using `sqlite` database - Fix problem with container update, that could ignore previous data stored in `mnesia` database - Revert limit of allowed characters in shared roster group names, that will again allow using symbols like `:` - Binary installers and `ejabberd` container image: Updated to Erlang/OTP 27.3.2 ### Full Changelog [https://github.com/processone/ejabberd/compare/25.03...25.04](https://github.com/processone/ejabberd/compare/25.03...25.04?ref=process-one.net) ## ejabberd 25.04 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Hello from the other side: Matrix ↔ XMPP via ejabberd 25.03 URL: https://www.process-one.net/blog/hello-from-the-other-side-matrix-xmpp-via-ejabberd-25-03/ Last updated: 2025-04-15T13:10:54.000Z With [ejabberd 25.03](https://www.process-one.net/blog/ejabberd-25-03/), the Matrix gateway (`mod_matrix_gw`) now supports not only one-to-one chats, but also joining Matrix rooms via XMPP. That’s right — your favorite XMPP client can now talk to Matrix users or hop into Matrix rooms just like regular MUCs. ✨ In this guide, we’ll show a quick demo of: 1. One-to-one chat between an XMPP and a Matrix user. 2. Joining a Matrix room and chatting from your XMPP client. And the best part? You don’t need to install a Matrix client at all. Keep your favorite XMPP client near, welcome to the magic of federation & interoperability. --- ## 🛠 Setup Summary We won’t repeat the full configuration steps here — they’re already covered in [this earlier blogpost](https://www.process-one.net/blog/matrix-gateway-setup-with-ejabberd/) and the [25.03 release note](https://www.process-one.net/blog/ejabberd-25-03/#matrix). In short, you’ll need: - A properly configured `ejabberd` server with `mod_matrix_gw` - Block outgoing connections to `lethe.matrix.org` to avoid conflicts with their XMPP instance Here’s a minimal config snippet: ```yaml listen: - port: 8448 module: ejabberd_http tls: true request_handlers: "/_matrix": mod_matrix_gw modules: mod_matrix_gw: key_name: "xxxxxx" key: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" matrix_id_as_jid: true ``` **Wondering what is the Matrix signing key?** Please refer to previous blog post: [Matrix gateway setup with ejabberd](https://www.process-one.net/blog/matrix-gateway-setup-with-ejabberd/#matrix-gateway-module) **Still not sure if your setup is correct?** Try [Matrix Federation Tester](https://federationtester.matrix.org/?ref=process-one.net) to check if everything is wired up properly. ## 🧪 One-to-One Chat (XMPP ↔ Matrix) In your XMPP client (e.g. Psi), add a Matrix contact using this format: `matrixUser%theirMatrixServer.tld@yourXMPPserver.tld` In my case, that means: `adrien-p1%matrix.org@matrix.mickael.m.in-app.io` On the Matrix side (e.g. Element Web), your contact will get a request. Once accepted, you’re good to chat! ✅ Demo: XMPP user (Psi) chats with Matrix user (Element Web) ## 🧪 Join a Matrix Room from your XMPP Client Alright, let’s join a public Matrix room now. From your XMPP client, you can join any Matrix public room using this format: `#matrixRoom%theirMatrixServer.tld@yourXMPPserver.tld` We’ll use the following room: `#ejabberd-demo:matrix.org`, so in my case, that means joining: `#ejabberd-demo%matrix.org@matrix.mickael.m.in-app.io` Once connected, you’ll be able to send and receive messages from any other participant, just like in a regular MUC. :) ✅ Demo: Join and chat in a Matrix room from XMPP ## 🐞 Known Caveats There's still a lot of work to do to make it seamless, here's a short list of currently known caveats: - Room presence can be overwhelming in large rooms (thousands of Matrix users may appear "online"). - No E2EE support between Matrix and XMPP — encryption must be disabled for now. - If the server restarts, 1-to-1 conversations must be restarted (re-added), as persistence is not implemented yet. - Only Matrix room protocol versions 9, 10, and 11 are supported. ## 🧵 Wrapping Up With this, **ejabberd** makes another step into being a powerful bridge into the Matrix federation, for both private and public communication. It’s a great way to keep using your favorite XMPP tools while staying connected to Matrix communities. Got feedback? Drop us a line in the comments or [open a PR](https://github.com/processone/ejabberd?ref=process-one.net). Happy bridging! 🙌 ### ejabberd 25.03 URL: https://www.process-one.net/blog/ejabberd-25-03/ Last updated: 2025-03-28T17:27:56.000Z **Release Highlights:** - **[Matrix Gateway Gets Room Support](#matrix)** - **[Multiple Simultaneous Password Types](#auth)** - **[Execute API Commands Using XMPP Client](#adhoc)** If you are upgrading from a previous version, please check the [changes in SQL schemas](#sql); but there aren't changes in the configuration, API commands or hooks. **Other contents:** - **[Macros and Keywords Improvements](#keyword)** - **[ejabberdctl: new option CTL\_OVER\_HTTP](#ctl%5Fover%5Fhttp)** - **[mod\_configure: new option access](#configure)** - **[Container images: reduce friction, use macros, webadmin port](#containers)** - **[ejabberd container image: admin account](#container-admin)** - **[Unix Domain Socket: relative path](#uds)** - **[Privileged Entity Bugfixes](#privilege)** - **[mod\_muc\_occupantid enabled by default](#occupantid)** - **[mod\_http\_api: return sorted list elements](#http)** - **[create\_room\_with\_opts API command separators](#create%5Froom%5Fwith%5Fopts)** - **[New API commands to change Mnesia table storage](#api-mnesia)** - **[Erlang/OTP and Elixir versions support](#erlang)** - **[Acknowledgments](#ack)** - **[Improvements in ejabberd Business Edition](#ebe)** - **[ChangeLog](#changelog)** - **[ejabberd 25.03 download & feedback](#download)** Below is a detailed breakdown of the improvements and enhancements: ## Matrix Gateway with Room Support ejabberd can bridge communications to [Matrix](https://matrix.org/?ref=process-one.net) servers since version 24.02 thanks to [mod\_matrix\_gw](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmatrix%5Fgw), 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: ```sh 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](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#auth%5Fstored%5Fpassword%5Ftypes), 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's 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](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#update%5Fsql%5Fschema) 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](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#new%5Fsql%5Fschema): - MySQL default schema: ```sql 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: ```sql 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: ```sql 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: ```sql 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: ```sql 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 '', salt text NOT NULL DEFAULT '', 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: ```sql 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 '', salt text NOT NULL DEFAULT '', 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](https://www.process-one.net/blog/ejabberd-24-06/#improved-webadmin-with-commands-usage): > 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](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net)... and now your XMPP client can execute them too! The new [mod\_adhoc\_api](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fhttp%5Fapi) ejabberd module allows to execute all the ejabberd API commands using a XMPP client that supports [XEP-0050 Ad-Hoc Commands](https://xmpp.org/extensions/xep-0050.html?ref=process-one.net) and [XEP-0030 Service Discovery](https://xmpp.org/extensions/xep-0030.html?ref=process-one.net). 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](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#reload%5Fconfig) the ejabberd configuration and login with your client to that account. Example configuration: ```yaml 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't 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](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fvcard) could used `HOST` in their `hosts` option. Other example is the [captcha\_cmd](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#captcha%5Fcmd) 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](https://docs.ejabberd.im/admin/configuration/file-format/?ref=process-one.net#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: ```yaml ext_api_url: "http://example.org/@VERSION@/api" ``` Additionally, now you can define your own keywords, similarly to how macros are defined: ```yaml 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: ```yaml 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](https://docs.ejabberd.im/admin/configuration/file-format/?ref=process-one.net#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](https://docs.ejabberd.im/admin/guide/managing/?ref=process-one.net#ejabberdctl) script is useful not only to start and stop ejabberd, it can also execute the \~200 ejabberd [API commands](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net) 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](https://docs.ejabberd.im/developer/ejabberd-api/?ref=process-one.net#understanding-ejabberd-commands) 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`: ```yaml listen: - port: "unix:sockets/ctl_over_http.sock" module: ejabberd_http unix_socket: mode: '0600' request_handlers: /ctl: ejabberd_ctl ``` Then enable the [CTL\_OVER\_HTTP](https://docs.ejabberd.im/admin/guide/managing/?ref=process-one.net#ctl%5Fover%5Fhttp) option in `ejabberdctl.cfg`: ```sh CTL_OVER_HTTP=sockets/ctl_over_http.sock ``` Let's register 100 accounts using the standard method and later using CTL\_OVER\_HTTP: ```sh $ 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](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fconfigure) always had support to configure what accounts can access its features: using the `configure` [access rule](https://docs.ejabberd.im/admin/configuration/basic/?ref=process-one.net#access-rules). 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](https://docs.ejabberd.im/CONTAINER/?ref=process-one.net) 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](https://docs.ejabberd.im/CONTAINER/?ref=process-one.net#images-comparison) 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's 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](https://docs.ejabberd.im/CONTAINER/?ref=process-one.net#macros-in-environment): ```yaml env: - name: PORT_HTTP_TLS value: 5444 ``` If you use the [podman-desktop](https://podman-desktop.io/?ref=process-one.net) or [docker-desktop](https://www.docker.com/products/docker-desktop/?ref=process-one.net) 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: ```yaml 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](https://docs.ejabberd.im/CONTAINER/?ref=process-one.net#commands-on-start) variable, and then you would need to modify `ejabberd.yml` accordingly: ```yaml 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't 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't check the packet type, and this check will also match a privileged-IQ *request* that is being sent to the same user that's 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's no circumstance under which we *shouldn't* forward a privileged-IQ response, so we don't 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't 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](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmuc%5Foccupantid) was added to the list of modules enabled in the sample configuration file `ejabberd.yml.example`. It's not necessarily obvious that it's required for using certain modern features in group chat, and there's no downside in activating this module. ## mod\_http\_api returns sorted list elements When [mod\_http\_api](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fhttp%5Fapi) 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](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#create%5Froom%5Fwith%5Fopts) 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't 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's 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't work at all): ```sh ejabberdctl \ create_room_with_opts \ room_old_separators \ conference.localhost \ localhost \ "persistent:true,affiliations:owner:user1@localhost,member:user2@localhost" ``` please use: ```sh 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's use `curl` to query [mod\_http\_api](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fhttp%5Fapi): ```sh curl -k -X POST -H "Content-type: application/json" \ "http://localhost:5280/api/create_room_with_opts" \ -d '{"name": "room_old_separators", "service": "conference.localhost", "host": "localhost", "options": [ {"name": "persistent", "value": "true"}, {"name": "affiliations", "value": "owner:user1@localhost,member:user2@localhost"} ] }' curl -k -X POST -H "Content-type: application/json" \ "http://localhost:5280/api/create_room_with_opts" \ -d '{"name": "room_new_separators", "service": "conference.localhost", "host": "localhost", "options": [ {"name": "persistent", "value": "true"}, {"name": "affiliations", "value": "owner=user1@localhost;member=user2@localhost"} ] }' ``` ## New API commands to change Mnesia table storage There are two new API commands: [mnesia\_list\_tables](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#mnesia%5Flist%5Ftables) and [mnesia\_table\_change\_storage](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#mnesia%5Ftable%5Fchange%5Fstorage). 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's review the supported [Erlang/OTP](https://www.erlang.org/?ref=process-one.net) 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](https://elixir-lang.org/?ref=process-one.net) 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: - [Dmitriy Bogdanov](https://github.com/di72nn?ref=process-one.net) for fixing documentation typos - [Holger Weiß](https://github.com/weiss?ref=process-one.net) for improving `xmpp`, `mod_private`, installers - [Linus Jahn](https://github.com/lnjX?ref=process-one.net) for fixing mix pam - [Matthew Stickney](https://github.com/mtstickney?ref=process-one.net) for fixing `mod_privilege` - [Pouriya Jahanbakhsh](https://github.com/pouriya?ref=process-one.net) for adding `c2s_handle_bind` event - [Saarko](https://github.com/sando38?ref=process-one.net) for `ejabberdapi` compilation in containers - [Stefan Strigler](https://github.com/sstrigler?ref=process-one.net) for `ext_mod` fixes and other - [Tamil Neram](https://github.com/TamilNeram?ref=process-one.net), added and completed a new Tamil translation - [Sketch6580](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net), updated the Chinese translation - [Максим Горпиніч](https://hosted.weblate.org/user/maksimgorpinic2005a/?ref=process-one.net), updated the Ukrainian translation And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), 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](https://github.com/processone/ejabberd/issues/4340?ref=process-one.net)) - `ejabberd_web_admin`: Support commands with tuple arguments - `mod_adhoc_api`: New module to execute API Commands using Ad-Hoc Commands ([#4357](https://github.com/processone/ejabberd/issues/4357?ref=process-one.net)) - `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](https://github.com/processone/ejabberd/issues/4337?ref=process-one.net)) - `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](https://github.com/processone/ejabberd/issues/4350?ref=process-one.net)) - `define_macro`: Add option to `globals()` because it's 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](https://github.com/processone/ejabberd/issues/4345?ref=process-one.net)) #### 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](https://github.com/processone/ejabberd/issues/4280?ref=process-one.net)) - `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't rewrite "self-addressed" privileged IQs as results ([#4348](https://github.com/processone/ejabberd/issues/4348?ref=process-one.net)) - `misc`: Fix json version of `json_encode_with_kv_list` for nested kv lists ([#4338](https://github.com/processone/ejabberd/issues/4338?ref=process-one.net)) - OAuth: Fix crashes when oauth is feed with invalid jid ([#4355](https://github.com/processone/ejabberd/issues/4355?ref=process-one.net)) - 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](https://github.com/processone/ejabberd/issues/4297?ref=process-one.net)) - `mod_muc`: Document MUC room option vcard\_xupdate - `mod_privilege`: Accept non-privileged IQs from privileged components ([#4341](https://github.com/processone/ejabberd/issues/4341?ref=process-one.net)) - `mod_private`: Improve exception handling - `mod_private`: Don't warn on conversion errors - `mod_private`: Handle invalid PEP-native bookmarks - `mod_private`: Don't crash on invalid bookmarks - `mod_s2s_bidi`: Stop processing other handlers in s2s\_in\_handle\_info ([#4344](https://github.com/processone/ejabberd/issues/4344?ref=process-one.net)) - `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](https://github.com/processone/ejabberd/issues/3041?ref=process-one.net)) - `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](https://github.com/processone/ejabberd/issues/4359?ref=process-one.net)) - `gen_mod`: Support registering commands and `hook_subscribe` in `start/2` result - `c2s_handle_bind`: New event in `ejabberd_c2s` ([#4356](https://github.com/processone/ejabberd/issues/4356?ref=process-one.net)) - `muc_disco_info_extras`: New event `mod_muc_room` useful for `mod_muc_webchat_url` ([#3041](https://github.com/processone/ejabberd/issues/3041?ref=process-one.net)) - 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't 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't build auto URL if port is unix domain socket ([#4345](https://github.com/processone/ejabberd/issues/4345?ref=process-one.net)) ### Full Changelog [https://github.com/processone/ejabberd/compare/24.12...25.03](https://github.com/processone/ejabberd/compare/24.12...25.03?ref=process-one.net) ## ejabberd 25.03 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Supporting XMPP Standard Foundation's open letter to Meta for true interop URL: https://www.process-one.net/blog/supporting-xmpp-standard-foundations-open-letter-to-meta-for-true-interop/ Last updated: 2025-03-28T14:25:10.000Z 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's [technical briefing](https://xmpp.org/announcements/open-letter-meta-dma/technical-briefing/?ref=process-one.net): > **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](https://xmpp.org/2025/03/open-letter-to-meta-support-true-messaging-interoperability-with-xmpp/?ref=process-one.net), 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. ### Join our community: Free Memberships now available URL: https://www.process-one.net/blog/join-our-community-free-memberships-now-available/ Last updated: 2026-03-19T14:58:52.000Z We’re excited to announce a new way to connect with our community at process-one.net. As of today, we’ve enabled free memberships on our site, giving you even more ways to stay updated, interact, and engage with our content. ## Why Sign Up? By becoming a member, you get access to specific benefits, including: - The ability to engage with our content in new ways, such as commenting on posts, participating in discussions like we did before and receiving exclusive insights. - A direct connection to the **ProcessOne** team and the latest updates on **ejabberd**, **Fluux.io**, technical insights and our other projects. - Email notifications when new articles are published. Ghost’s (our blogging platform, right here) membership is designed to help build an engaged community. It allows users to stay informed, participate actively, and create a closer connection, without any cost or commitment, while ensuring our content remains valuable to a genuine human audience. It means we are re-enabling comments here (disabled while we switched away from our Wordpress instance), which is the most important aspect of this membership. We have **no plans for paid memberships**; our goal is simply to share updates about our projects and the XMPP ecosystem. Additionally, we respect your privacy: your email will only be used to notify you about new content, and we will never sell it. ## It's Free and easy to join. Signing up is completely **free:** just create an account and start enjoying the benefits right away. No strings attached! ## Prefer RSS? We’ve Got You Covered If you prefer to follow updates through RSS, you can always subscribe to our feed and get the latest content delivered straight to your reader of choice. [Subscribe over here](https://www.process-one.net/rss). ;). We’re always looking for new ways to enhance the experience for our readers, and this is just the beginning. We hope you’ll join us and be part of our growing community! [Sign up today](https://www.process-one.net/#/portal/signup) and stay connected! ### How Big Tech Pulled Off the Billion-User Heist URL: https://www.process-one.net/blog/how-big-tech-pulled-off-the-billion-user-heist/ Last updated: 2025-01-16T16:17:13.000Z For many years, I have heard countless justifications for keeping messaging systems closed. Many of us have tried to rationalize walled gardens for various reasons: - Closed messaging systems supposedly enable faster progress, as there’s no need to collaborate on shared specifications or APIs. You can change course more easily. - Closed messaging systems are better for security, spam, or whatever other risks we imagine, because owners feel they have better control of what goes in and out. - Closed messaging systems are said to foster innovation by protecting the network owner’s investments. But is any of this really true? Let’s take a step back and examine these claims. ## A Brief History of Messaging Tools Until the 1990s, messaging systems were primarily focused on building communities. The dominant protocol of the time was **IRC (Internet Relay Chat)**. While IRC allowed private messaging, its main purpose was to facilitate large chatrooms where people with shared interests could hang out and interact. In the 1990s, messaging evolved into a true communication tool, offering an alternative to phone calls. It enabled users to stay in touch with friends and family while forging new connections online. With the limitations of the dial-up era, where users weren’t always connected, **asynchronous communication** became the norm. Features like **offline** messages and **presence** indicators emerged, allowing users to see at a glance who was online, available, or busy. The revolution began with **ICQ**, quickly followed by competitors like **Yahoo! Messenger** and **MSN Messenger**. However, this proliferation of platforms created a frustrating experience: your contacts were spread across different networks, requiring multiple accounts and clients. Multiprotocol clients like Meebo and Pidgin emerged, offering a unified interface for these networks. Still, they often relied on unofficial protocol implementations, which were unreliable and lacked key features compared to native clients. To address these issues, a group of innovators in 1999 set out to design a better solution—an **open instant messaging protocol** that revolved around two fundamental principles: 1. **Federation**: A federated protocol would allow users on any server to communicate seamlessly with users on other servers. This design was essential for scalability, as supporting billions of users on a single platform was unimaginable at the time. 2. **Gateway Support**: The protocol would include gateways to existing networks, enabling users to connect with contacts on other platforms transparently, without needing to juggle multiple applications. The gateways were implemented on the server-side, allowing fast iterations on gateway code. This initiative, originally branded as **Jabber**, gave rise to **XMPP (Extensible Messaging and Presence Protocol)**, a protocol standardized by the IETF. XMPP gained traction, with support from several open-source servers and clients. Major players adopted the protocol—Google for **Google Talk** and Facebook for **Facebook Messenger**, enabling third-party XMPP clients to connect to their services. The future of open messaging looked promising. ## Fast Forward 20 Years Today, that optimism has faded. Few people know about XMPP or its newer counterpart, Matrix. Google’s messaging services have abandoned XMPP, Facebook has closed its XMPP gateways, and the landscape has returned to the fragmentation of the past. Instead of Yahoo! Messenger and MSN, we now deal with **WhatsApp**, **Facebook Messenger**, **Telegram**, **Google Chat**, **Signal**, and even messaging features within social networks like Instagram and LinkedIn. Our contacts are scattered across these platforms, forcing us to switch between apps just as we did in the 1990s. ## What Went Wrong? Many of these platforms initially adopted XMPP, including Google, Facebook, and even WhatsApp. However, their focus on growth led them to abandon federation. Requiring users to create platform-specific accounts became a key strategy for locking in users and driving their friends to join the same network. Federation, while technically advantageous, was seen as a barrier to user acquisition and growth. ## The Big Heist The smartphone era marked a turning point in messaging, fueled by always-on connectivity and the rise of app stores. Previously, deploying an app at scale required agreements with mobile carriers to preload the app on the phones they sold. Carriers acted as gatekeepers, tightly controlling app distribution. However, the introduction of app stores and data plans changed everything. These innovations empowered developers to bypass carriers and build their own networks on top of carrier infrastructure—a phenomenon known as **over-the-top (OTT) applications**. Among these new apps was **WhatsApp**, which revolutionized messaging in several ways. Initially, WhatsApp relied on Apple’s Push Notification Service to deliver messages in real time, bypassing the need for a complex infrastructure at launch. Its true breakthrough, however, was the decision to use **phone numbers as user identifiers**—a bold move that set a significant precedent. At the time, most messaging platforms avoided this approach because phone numbers were closely tied to SMS, and validating them via SMS codes came with significant costs. WhatsApp cleverly leveraged this existing, international system of telecommunication identifiers to bootstrap its proprietary network. By using phone numbers, it eliminated the need for users to create, manage and share separate accounts, simplifying onboarding. WhatsApp also capitalized on the high cost of SMS at the time. Since short messages were often not unlimited, and international SMS was especially expensive, many users found it cheaper to rely on data plans or Wi-Fi to message friends and family—particularly across borders. When we launched our own messaging app, **TextOne** (now discontinued), we considered using phone numbers as identifiers but ultimately decided against it. Forcing users to disclose such personal information felt intrusive and misaligned with privacy principles. By then, the phone had shifted from being a shared household device to a deeply personal one, making phone numbers uniquely tied to individual identities. Later, Whatsapp launched its own infrastructure based on ejabberd, but they kept their service closed. At that time, we also considered using phone number when launching our own messaging app, the now discontinued TextOne, but refused to use that. It did not feel right, as you were forcing people to disclose an important private information. As the phone had become a personnal device, instead of a household device, the phone number played the role of unique identifier for a single individual. Unfortunately, most major players seeking to scale their messaging platforms adopted the phone number as a universal identifier. WhatsApp’s early adoption of this strategy helped it rapidly amass a billion users, giving it a decisive first-mover advantage. However, it wasn’t the only player to recognize and exploit the power of phone numbers in building massive-scale networks. Today, the phone number is arguably the most accurate global identifier for individuals, serving as a cornerstone of the flourishing data economy. ## What’s Wrong With Using Phone Numbers as IDs? Phone numbers are a **common good**—a foundation of global communication. They rely on the principle of universal accessibility: you can reach anyone, anywhere in the world, regardless of their phone provider or location. This system was built on international cooperation, with a branch of the United Nations playing a key role in maintaining a provider-agnostic, interoperable platform. At its core is a globally unique phone numbering system, created through collaborative standards and protocols. However, **over-the-top (OTT) companies** have exploited this infrastructure to build private networks on top of the public system. They’ve leveraged the universal identification scheme of phone numbers—and, by extension, the global interoperable network—to construct proprietary, closed ecosystems. To me, this feels like a misuse of a common good. Phone numbers, produced through international cooperation, should not be appropriated freely by private corporations without accountability. While it may be too late to reverse this trend, we should consider a **contribution system** for companies that store and use phone numbers as identifiers. For example, companies that maintain databases with millions of unique phone numbers could be required to pay an annual fee for each phone number they store. This fee could be distributed to the countries associated with those numbers. Such a system would achieve two things: 1. **Encourage Accountability**: Companies would need to evaluate whether collecting and storing phone numbers is truly essential for their business. If the data isn’t valuable enough to justify the cost, they might choose not to collect it. 2. **Promote Fairness**: For companies that rely heavily on phone numbers to track, match, and build private, non-interoperable services, this fee would act as a fair contribution, akin to taxes paid for using public road infrastructure. It looks a lot to me that the phone number is a common good produced and use by international cooperation. It is too late to prevent it to be used by Big Tech companies. However, it may seem fair to imagine a contribution from company storing phone number. This is a data that is not their property and not theirs to use. Shouldn't we consider a tax on phone numbers storage and usage ? For example, if a company store a millions unique phone number in their database, why not require a yearly fee, to be paid to each country that any phone number is associated to, one yearly fee per phone number ? Company would have to think twice about storing such personnal data. Is it valuable for your business ? If it is not valuable enough, fair enough, delete them and do not ask them, but if you need it to trakt and match user and build a private non interoperable service, then paying a fair contribution for their usage should be considered. It would be like the tax they pay to leverage road infrastructure in countries where they operate. ## Beyond Taxes: The Push for Interoperability Of course, a contribution system alone won’t solve the larger issue. We also need a significant push toward **interoperable and federated messaging**. While the [**European Digital Markets Act (DMA)**](https://digital-markets-act.ec.europa.eu/index%5Fen?ref=process-one.net) includes an interoperability requirement, it doesn’t go far enough. Interoperability alone cannot address the challenges of closed ecosystems. I’ll delve deeper into why interoperability must be paired with federation in a future article, as this is a critical piece of the puzzle. ## Interoperability vs. Velocity To conclude, I’d like to reference the introduction of the [IETF SPIN draft](https://www.ietf.org/archive/id/draft-rosenberg-mimi-spin-00.html?ref=process-one.net), which perfectly encapsulates the trade-offs between interoperability and innovation: > Voice, video and messaging today is commonplace on the Internet, enabled by two distinct classes of software. The first are those provided by telecommunications carriers that make heavy use of standards, such as the Session Initiation Protocol (SIP) \[RFC3261\]. In this approach - which we call the telco model - there is interoperability between different telcos, but the set of features and functionality is limited by the rate of definition and adoption of standards, often measured in years or decades. The second model - the app model - allows a single entity to offer an application, delivering both the server side software and its corresponding client-side software. The client-side software is delivered either as a web application, or as a mobile application through a mobile operating system app store. The app model has proven incredibly successful by any measure. **It trades off interoperability for innovation and velocity.** > > The downside of the loss of interoperability is that entry into the market place by new providers is difficult. Applications like WhatsApp, Facebook Messenger, and Facetime, have user bases numbering in the hundreds of millions to billions of users. Any new application cannot connect with these user bases, requiring the vendor of the new app to bootstrap its own network effects. This summary aligns closely with the ideas I’ve explored in this article. I believe we’ve reached a point where we need **interoperability** far more than continued innovation in voice, video, and messaging. While innovation in these areas has been remarkable, we have perhaps been too eager—or too blind—to sacrifice interoperability in the name of progress. Now, the pendulum is poised to swing back. **Centralization must give way to federation** if we are to maintain the universality that once defined global communication. Without federation, there can be no true global and universal service, and without universality, we risk regressing, fragmenting all our communication systems into isolated and proprietary silos. It’s time to prioritize interoperability, to reclaim the vision of a truly connected world where communication is open, accessible, and universal. ### Fluux multiple Subscriptions/Services URL: https://www.process-one.net/blog/fluux-multiple-subscriptions-services/ Last updated: 2025-01-15T16:27:31.000Z Fluux is our ejabberd Business Edition cloud service. With a subscription, we deploy, manage, update and scale an instance of our most scalable messaging server. Up to now, if you wanted to deploy several services, you had to create another account with a different email. Starting today, you can manage and pay for different servers from a single Fluux account. Here is how to use that feature. On Fluux dashboard main page after the list of your service/platforms you may have noticed a "New" button. ![](https://www.process-one.net/content/images/2025/01/Screenshot-2025-01-15-at-10.36.56.png) You will be then redirected on a page to choose your plan. ![](https://www.process-one.net/content/images/2025/01/Screenshot-2025-01-13-at-19.04.54.png) Once terms and conditions are approved, you will be able to fill your card information on a page hosted by our payment provider. ![](https://www.process-one.net/content/images/2025/01/Screenshot-2025-01-13-at-19.06.10.png) When payment is succeeded, you will be then redirected to Fluux console and a link create your service: ![](https://www.process-one.net/content/images/2025/01/Screenshot-2025-01-15-at-15.26.01.png) On this last page you will be able to provide a technical name that will be used to provision your Fluux service. ![](https://www.process-one.net/content/images/2025/01/Screenshot-2025-01-15-at-15.33.17.png) After 10 minutes you can enjoy your new service at techname.m.in-app.io (such test1.m.in-app.io in above screenshot) ### ejabberd 24.12 URL: https://www.process-one.net/blog/ejabberd-24-12/ Last updated: 2024-12-20T10:15:47.000Z Here comes ejabberd 24.12, including a few improvements and bug fixes. This release comes a month and half after 24.10, with around 60 commits to the core repository alongside a few updates in dependencies. **Release Highlights:** - **[XEP-0484: Fast Authentication Streamlining Tokens](#484)**: Reduce the time it takes for authentication. This helps with a faster start for clients on mobile. - **[Deprecation schedule for Erlang/OTP older than 25.0](#erlang25)** - **[Commands API v3](#apiv3)**: We paved the way for API changes and improvements while allowing customers depending on older version to stay on a pinned version of the commands. Among them, the `evacuate_kindly` command is a new tool which gave the funny codename to this release. It lets you stop and rerun ejabberd without letting users reconnect to let you perform your maintenance task peacefully. So, this is not an emergency exit from ejabberd, but instead testimony that this releasing is paving the way for a lot of new cool stuff in 2025. In the meantime, we wish you a **Merry Christmas** and a **Happy New Year**! **Other contents:** - **[Improvements in commands](#commands)** - **[Use non-standard STUN port](#stun)** - **[Disable the systemd watchdog by default](#watchdog)** - **[Define macro as environment variable](#macro)** - **[Elixir modules for authentication](#elixir)** - **[Redis now supports Unix Domain Socket](#redis)** - **[New evacuate\_kindly command](#evacuate)** - **[Acknowledgments](#ack)** - **[Improvements in ejabberd Business Edition](#ebe)** - **[ChangeLog](#changelog)** - **[ejabberd 24.12 download & feedback](#download)** If you are upgrading from a previous version, there are no required changes in the SQL schemas, configuration or hooks. There are some [Commands API v3](#apiv3). Below is a detailed breakdown of the improvements and enhancements: ## XEP-0484: Fast Authentication Streamlining Tokens We added support for [XEP-0484: Fast Authentication Streamlining Tokens](https://xmpp.org/extensions/xep-0484.html?ref=process-one.net). This allows clients to request time limited tokens from servers, which then can be later used for faster authentication by requiring less round trips. To enable this feature, you need to add `mod_auth_fast` module in `modules` section. ## Deprecation schedule for Erlang/OTP older than 25.0 It is expected that around April 2025, GitHub Actions will remove Ubuntu 20 and it will not be possible to run automatically dynamic tests for ejabberd using Erlang/OTP older than 25.0. For that reason, the planned schedule is: - **ejabberd 24.12** - Usage of Erlang/OTP older than 25.0 is still supported, but **discouraged** - Anybody still using Erlang 24.3 down to 20.0 is encouraged to upgrade to a newer version. Erlang/OTP 25.0 and higher are supported. For instance, Erlang/OTP 26.3 is used for the binary installers and container images. - **ejabberd 25.01** (or later) - Support for Erlang/OTP older than 25.0 is **deprecated** - Erlang requirement softly increased in `configure.ac` - Announce: no warranty ejabberd can compile, start or pass the Common Tests suite using Erlang/OTP older than 25.0 - Provide instructions for anybody to manually re-enable it and run the tests - **ejabberd 25.01+1** (or later) - Support for Erlang/OTP older than 25.0 is **removed** completely in the source code ## Commands API v3 This ejabberd 24.12 release introduces ejabberd Commands API v3 because some commands have changed arguments and result formatting. You can continue using API v2; or you can update your API client to use API v3\. Check the [API Versions History](https://docs.ejabberd.im/developer/ejabberd-api/api%5Fversioning/?ref=process-one.net#api-versions-history). Some commands that accepted accounts or rooms as arguments, or returned JIDs, have changed their arguments and results names and format to be consistent with the other commands: - Arguments that refer to a user account are now named `user` and `host` - Arguments that refer to a MUC room are now named `room` and `service` - As seen, each argument is now only the local or server part, not the JID - On the other hand, results that refer to user account or MUC room are now the JID In practice, the commands that change in API v3 are: - [get\_room\_affiliations](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get%5Froom%5Faffiliations) - [muc\_register\_nick](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#muc%5Fregister%5Fnick) - [muc\_unregister\_nick](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#muc%5Funregister%5Fnick) - [set\_room\_affiliation](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#set%5Froom%5Faffiliation) - [status\_list](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#status%5Flist) - [status\_list\_host](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#status%5Flist%5Fhost) - [subscribe\_room](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#subscribe%5Froom) - [subscribe\_room\_many](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#subscribe%5Froom%5Fmany) - [unsubscribe\_room](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#unsubscribe%5Froom) If you want to update ejabberd to 24.12, but prefer to continue using an old API version with `mod_http_api`, you can set this new option: ```yaml modules: mod_http_api: default_version: 2 ``` ## Improvements in commands There are a few improvements in some commands: - `create_rooms_file`: Improved, now it supports vhosts with different config - `evacuate_kindly`: New command to kick users and prevent login ([#4309](https://github.com/processone/ejabberd/issues/4309?ref=process-one.net)) - `join_cluster`: Improved explanation: this returns immediately (since 5a34020, 24.06) - `mod_muc_admin`: Renamed arguments `name` to `room` for consistency, with backwards support (no need to update API clients) ## Use non-standard STUN port STUN via UDP can easily be abused for reflection/amplification DDoS attacks. Suggest a non-standard port to make it harder for attackers to discover the service in `ejabberd.yml.example`. Modern XMPP clients discover the port via XEP-0215, so there's no advantage in sticking to the standard port. ## Disable the systemd watchdog by default Some users reported ejabberd being restarted by systemd due to missing watchdog pings despite the actual service operating just fine. So far, we weren't able to track down the issue, so we'll no longer enable the watchdog in our example service unit. ## Define macro as environment variable ejabberd allows you to [define macros](https://docs.ejabberd.im/admin/configuration/file-format/?ref=process-one.net#macros-in-configuration-file) in the configuration file since version 13.10\. This allows to define a value once at the beginning of the configuration file, and use that macro to setup options values several times during the file. Now it is possible to define the macro value as an environment variable. The environment variable name should be `EJABBERD_MACRO_ + macro name`. For example, if you configured in `ejabberd.yml`: ```yaml define_macro: LOGLEVEL: 4 loglevel: LOGLEVEL ``` Now you can define (and overwrite) that macro definition when starting ejabberd. For example, if starting ejabberd in interactive mode: ```bash EJABBERD_MACRO_LOGLEVEL=5 make relive ``` This is specially useful when using containers with slightly different values (different host, different port numbers...): instead of having a different configuration file for each container, now you can use a macro in your custom configuration file, and define different macro values as environment variable when starting each container. See some examples usages in [CONTAINER's composer examples](https://docs.ejabberd.im/CONTAINER/?ref=process-one.net#composer-examples) ## Elixir modules for authentication [ejabberd modules](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net) can be written in the [Elixir](https://elixir-lang.org/?ref=process-one.net) programming language since ejabberd 15.02\. And now, ejabberd [authentication methods](https://docs.ejabberd.im/admin/configuration/authentication/?ref=process-one.net#supported-methods) can also be written in Elixir! This means you can write a custom authentication method in Erlang or in Elixir, or write an [external authentication script](https://docs.ejabberd.im/admin/configuration/authentication/?ref=process-one.net#external-script) in any language you want. There's an example authentication method in the `lib/` directory. Place your custom authentication method in that directory, compile ejabberd, and configure it in `ejabberd.yml`: ```yaml auth_method: 'Ejabberd.Auth.Example' ``` For consistency with that file naming scheme, the old `mod_presence_demo.ex` has been renamed to `mod_example.ex`. Other minor changes were done on the Elixir example code. ## Redis now supports Unix Domain Socket Support for Unix Domain Socket was added to [listener's port option](https://docs.ejabberd.im/admin/configuration/listen-options/?ref=process-one.net#port) in ejabberd 20.07\. And more recently, ejabberd 24.06 added support in [sql\_server](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#sql%5Fserver) when using MySQL or PostgreSQL. That feature is useful to improve performance and security when those programs are running on the same machine as ejabberd. Now the [redis\_server](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#redis%5Fserver) option also supports Unix Domain Socket. The syntax is similar to the other options, simply setup `unix:` followed with the full path to the socket file. For example: ```yaml redis_server: "unix:/var/run/redis/redis.socket" ``` Additionally, we took the opportunity to update from the [wooga/eredis](https://github.com/wooga/eredis/?ref=process-one.net) erlang library which hasn't been updated in the last six years, to the [Nordix/eredis](https://github.com/Nordix/eredis?ref=process-one.net) fork which is actively maintained. ## New `evacuate_kindly` command ejabberd has nowadays around 180 commands to perform many administrative tasks. Let's review some of their usage cases: - Did you modify the configuration file? [Reload the configuration](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#reload%5Fconfig) file and apply its changes - Did you apply some patch to ejabberd source code? Compile and install it, and then [update](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#update) the module binary in memory - Did you update [ejabberd-contrib](https://github.com/processone/ejabberd-contrib?ref=process-one.net) specs, or improved your custom module in `.ejabberd-module`? Call [module\_upgrade](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#module%5Fupgrade) to compile and upgrade it into memory - Did you upgrade ejabberd, and that includes many changes? Compile and install it, then [restart](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#restart) ejabberd completely - Do you need to stop a production ejabberd which has users connected? [stop\_kindly](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#stop%5Fkindly) the server, informing users and rooms - Do you want to stop ejabberd gracefully? Then simply [stop](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#stop) it - Do you need to stop ejabberd immediately, without worrying about the users? You can [halt](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#halt) ejabberd abruptly Now there is a new command, [evacuate\_kindly](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#evacuate%5Fkindly), useful when you need ejabberd running to perform some administrative task, but you don't want users connected while you perform those tasks. It stops port listeners to prevent new client or server connections, informs users and rooms, and waits a few seconds or minutes, then restarts ejabberd. However, when ejabberd is started again, the port listeners are stopped: this allows to perform administrative tasks, for example in the database, without having to worry about users. For example, assuming ejabberd is running and has users connected. First let's evacuate all the users: ```sh ejabberdctl evacuate_kindly 60 \"The server will stop in one minute.\" ``` Wait one minute, then ejabberd gets restarted with connections disabled. Now you can perform any administrative tasks that you need. Once everything is ready to accept user connections again, simply restart ejabberd: ```sh ejabberdctl restart ``` ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Holger Weiß](https://github.com/weiss?ref=process-one.net) for PEP and other fixes - [Marcos de Vera Piquero](https://github.com/marc0s?ref=process-one.net) for Elixir auth support - [Mark Zealey](https://github.com/mzealey?ref=process-one.net) for WebSockets fix - [Mr. EddX](https://github.com/MrEddX?ref=process-one.net), updated the Bulgarian translation - [Nautilusx](https://hosted.weblate.org/user/nautilusx/?ref=process-one.net), updated the German translation - [ButterflyOfFire](https://hosted.weblate.org/user/boffire/?ref=process-one.net), updated the French translation - [Ermete Melchiorre](https://github.com/sudcapitano?ref=process-one.net), updated the Italian translation - [Wellington Uemura](https://github.com/wtuemura?ref=process-one.net), updated the Portuguese (Brazil) - [Besnik Bleta](https://github.com/ujdhesa?ref=process-one.net), updated the Albanian translation - [Sketch6580](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net), updated the Chinese translation And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get support for Prometheus. ### Prometheus support [Prometheus](https://prometheus.io/?ref=process-one.net) can now be used as a backend for `mod_mon` in addition to statsd, influxdb, influxdb2, datadog and dogstatsd. You can expose all `mod_mon` metrics to Prometheus by adding a http listener pointing to `mod_prometheus`, for example: ```yaml - port: 5280 module: ejabberd_http request_handlers: "/metrics": mod_prometheus ``` You can then add a scrape config to Prometheus for ejabberd: ```yaml scrape_configs: - job_name: "ejabberd" static_configs: - targets: - "ejabberd.domain.com:5280" ``` You can also limit the metrics to a specific virtual host by adding it's name to the path: ```yaml scrape_configs: - job_name: "ejabberd" static_configs: - targets: - "ejabberd.domain.com:5280" metrics_path: /metrics/myvhost.domain.com ``` ### Fix - PubSub: fix issue on `get_item_name` with p1db storage backend. ## ChangeLog This is a more detailed list of changes in this ejabberd release: #### Miscelanea - Elixir: support loading Elixir modules for auth ([#4315](https://github.com/processone/ejabberd/issues/4315?ref=process-one.net)) - Environment variables `EJABBERD_MACRO` to define macros - Fix problem starting ejabberd when first host uses SQL, other one mnesia - HTTP Websocket: Enable `allow_unencrypted_sasl2` on websockets ([#4323](https://github.com/processone/ejabberd/issues/4323?ref=process-one.net)) - Relax checks for channels bindings for connections using external encryption - Redis: Add support for unix domain socket ([#4318](https://github.com/processone/ejabberd/issues/4318?ref=process-one.net)) - Redis: Use eredis 1.7.1 from Nordix when using mix/rebar3 and Erlang 21+ - `mod_auth_fast`: New module with support XEP-0484: Fast Authentication Streamlining Tokens - `mod_http_api`: Fix crash when module not enabled (for example, in CT tests) - `mod_http_api`: New option `default_version` - `mod_muc`: Make rsm handling in disco items, correctly count skipped rooms - `mod_offline`: Only delete offline msgs when user has MAM enabled ([#4287](https://github.com/processone/ejabberd/issues/4287?ref=process-one.net)) - `mod_priviled`: Handle properly roster iq - `mod_pubsub`: Send notifications on PEP item retract - `mod_s2s_bidi`: Catch extra case in check for s2s bidi element - `mod_scram_upgrade`: Don't abort the upgrade - `mod_shared_roster`: The name of a new group is lowercased - `mod_shared_roster`: Get back support for `groupid@vhost` in `displayed` #### Commands API - Change arguments and result to consistent names (API v3) - `create_rooms_file`: Improve to support vhosts with different config - `evacuate_kindly`: New command to kick users and prevent login ([#4309](https://github.com/processone/ejabberd/issues/4309?ref=process-one.net)) - `join_cluster`: Explain that this returns immediately (since 5a34020, 24.06) - `mod_muc_admin`: Rename argument `name` to `room` for consistency #### Documentation - Fix some documentation syntax, add links to toplevel, modules and API - `CONTAINER.md`: Add kubernetes yaml examples to use with podman - `SECURITY.md`: Add security policy and reporting guidelines - `ejabberd.service`: Disable the systemd watchdog by default - `ejabberd.yml.example`: Use non-standard STUN port #### WebAdmin - Shared group names are case sensitive, use original case instead of lowercase - Use lowercase username and server authentication credentials - Fix calculation of node's uptime days - Fix link to displayed group when it is from another vhost ### Full Changelog [https://github.com/processone/ejabberd/compare/24.10...24.12](https://github.com/processone/ejabberd/compare/24.10...24.12?ref=process-one.net) ## ejabberd 24.12 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Docker: Keep ejabberd automagically updated with Watchtower URL: https://www.process-one.net/blog/docker-ejabberd-watchtower/ Last updated: 2026-03-19T15:01:06.000Z This blog post will guide you through the process of setting up an **ejabberd Community Server** using *Docker* and *Docker Compose*, and will also introduce **Watchtower** for automatic updates. This approach ensures that your configuration remains secure and up to date. Furthermore, we will examine the potential risks associated with automatic updates and suggest **Diun** as an alternative tool for notification-based updates. ## 1\. Prerequisites Please ensure that Docker and Docker Compose are installed on your system. It would be beneficial to have a basic understanding of Docker concepts, including containers, volumes, and bind-mounts. ## 2\. Set up ejabberd in a docker container Let’s first create a minimal Docker Compose configuration to start an ejabberd instance. ### 2.1: Prepare the directories For this setup, we will create a directory structure to store the configuration, database, and logs. This will assist in maintaining an organised setup, facilitating data management and backup. ```bash mkdir ejabberd-setup && cd ejabberd-setup touch docker-compose.yml mkdir conf touch conf/ejabberd.yml mkdir database mkdir logs ``` This should give you the following structure: ```bash ejabberd-setup/ ├── conf │   └── ejabberd.yml ├── database ├── docker-compose.yml └── logs ``` To verify the structure, use the `tree` command. It is a very useful tool which we use on a daily basis. #### Set permissions Since we'll be using bind mounts in this example, it’s important to ensure that specific directories (like database and logs) have the correct permissions for the ejabberd user inside the container (UID `9000`, GID `9000`). Customize or skip depending on your needs: ```bash sudo chown -R 9000:9000 database sudo chown -R 9000:9000 logs ``` *Based on this [Issue](https://github.com/processone/docker-ejabberd/issues/26?ref=process-one.net)*. ### 2.2: The `docker-compose.yml` file Now, create a `docker-compose.yml` file inside, containing: ```yaml services: ejabberd: image: ejabberd/ecs:latest container_name: ejabberd ports: - "5222:5222" # XMPP Client - "5280:5280" # Web Admin Interface, optional volumes: - ./database:/home/ejabberd/database - ./ejabberd.yml:/home/ejabberd/conf/ejabberd.yml - ./logs:/home/ejabberd/logs restart: unless-stopped ``` ### 2.3: The `ejabberd.yml` file A basic configuration file for ejabberd will be required. we will name it `conf/ejabberd.yml`. ```yaml loglevel: 4 hosts: - "localhost" acl: admin: user: - "admin@localhost" access_rules: local: allow: all listen - port: 5222 module: ejabberd_c2s - port: 5280 # optional module: ejabberd_http # optional request_handlers: # optional "/admin": ejabberd_web_admin # optional ``` > Did you know? Since [23.10](https://docs.ejabberd.im/archive/23.10/?ref=process-one.net), ejabberd now offers users the option to create or update the relevant MySQL, PostgreSQL or SQLite tables automatically with each update. You can read more about it [here](https://docs.ejabberd.im/tutorials/mysql/?ref=process-one.net#use-automatic-schema-update). ## 3: Starting ejabberd Finally, we're set: you can run the following command to start your stack: `docker-compose up -d` Your ejabberd instance should now running in a Docker container! Good job! 🎉 From there, customize ejabberd to your liking! Naturally, in this example we're going to keep ejabberd in its barebones configuration, but we recommend that you configure it as you wish at this stage, to suit your needs (Domains, SSL, favorite modules, chosen database, admin accounts, etc.) ### Example: You could register your admin account at this stage To use the admin interface, you need to create an admin account. You can do so by running the following command: ```bash $ docker exec -it ejabberd bin/ejabberdctl register admin localhost very_secret_password > User admin@localhost successfully registered ``` Once this step is complete, you will then be able to access the web admin interface at [http://localhost:5280/admin](http://localhost:5280/admin?ref=process-one.net). ## 4\. Set up automatic updates Finally, we come to the most interesting part: **how do I keep my containers up to date?** To keep your ejabberd instance up-to-date, you can use [Watchtower](https://github.com/containrrr/watchtower/?ref=process-one.net), a Docker container that automatically updates other containers when new versions are available. > Warning: Auto-updates are undoubtedly convenient, but they can occasionally cause issues if an update includes breaking changes. Always test updates in a staging environment and back up your data before enabling auto-updates. Further information can be found at the end of this post. If greater control over updates is required (for example, for mission-critical production servers or clusters), we recommend using [Diun](https://github.com/crazy-max/diun?ref=process-one.net), which can notify you of available updates and allow you to decide when to apply them. ### 4.1: Add Watchtower to your `docker-compose.yml` To include [Watchtower](https://github.com/containrrr/watchtower/?ref=process-one.net), add it as a service in `docker-compose.yml`: ```yaml services: ejabberd: image: ejabberd/ecs:latest container_name: ejabberd ports: - "5222:5222" # XMPP Client - "5280:5280" # Web Admin Interface, optional volumes: - ./database:/home/ejabberd/database - ./ejabberd.yml:/home/ejabberd/conf/ejabberd.yml - ./logs:/home/ejabberd/logs restart: unless-stopped watchtower: image: containrrr/watchtower container_name: watchtower volumes: - /var/run/docker.sock:/var/run/docker.sock environment: - WATCHTOWER_POLL_INTERVAL=3600 # Sets how often Watchtower checks for updates (in seconds). - WATCHTOWER_CLEANUP=true # Ensures old images are cleaned up after updating. restart: unless-stopped ``` [Watchtower](https://github.com/containrrr/watchtower/?ref=process-one.net) offers a wide range of additional features, including the ability to set up notifications, exclude specific containers, and more. For further information, please refer to the [Watchtower Docs](https://containrrr.dev/watchtower/usage-overview/?ref=process-one.net). Once the `docker-compose.yml` has been updated, please bring it up using the following command: `docker-compose up -d` And.... here you go, you're all set! ## 5\. Best Practices & closing words Now [Watchtower](https://github.com/containrrr/watchtower/?ref=process-one.net) will now perform periodic checks for updates to your `ejabberd` container and apply them automatically. Well to be fair, by default if other containers are running on the same server, Watchtower will also update them. This behaviour can be controlled with the help of environment variables (see [Container Selection](https://containrrr.dev/watchtower/container-selection/?ref=process-one.net)), which will assist in excluding containers from updates. --- One important thing to understand is that Watchtower will only update containers tagged with the `:latest` tag. In an environment with numerous Docker containers, using the `latest` tag streamlines the process of automatic updates. However, it may introduce unanticipated changes with each new, disruptive update. Ideally, we recommend always setting a speficic version like `ejabberd/ecs:24.10` and deciding how/when to update it manually (especially if you're into [infra-as-code](https://fr.wikipedia.org/wiki/Infrastructure%5Fas%5Fcode?ref=process-one.net)). However, we recognise that some users may prefer the convenience of automatic updates, personnally that's what I do my homelab but I'm not scared to dig in if stuff breaks. --- **tl;dr:** For a small community server/homelab/personnal instance, Watchtower will help keep things up to date with minimal effort. However, for bigger production environments, it is advisable to tag specific versions to ensure greater control and resilience and update them manually. With this setup, you now have a fully functioning XMPP server using ejabberd, with automatic updates. You can now start building your chat applications or integrate it with your existing services! 🚀 ### Thoughts on Improving Messaging Protocols — Part 2, Matrix URL: https://www.process-one.net/blog/thoughts-on-improving-messaging-protocols-part-2-matrix/ Last updated: 2024-11-05T13:53:01.000Z In the [first part of this blog post](https://www.process-one.net/blog/matrix-and-xmpp-thoughts-on-improving-messaging-protocols-part-1/), I explained how the Matrix protocol works, contrasted its design philosophy with XMPP, and discussed why these differences lead to performance costs in Matrix. Matrix processes each conversation as a graph of events, merged in real-time\[1\]. Merge operations can be costly in Matrix for large rooms, affecting both [database storage and load](https://github.com/element-hq/synapse/issues/17470?ref=process-one.net) and [disk usage when memory is exhausted, reaching swap level](https://github.com/element-hq/synapse/issues/17129?ref=process-one.net). That said, there is still room for improvement in the protocol. We have designed and tested slight changes that could make Matrix much more efficient for large rooms. ## A Proposal to Simplify and Speed Up Merge Operations Here is the rationale behind a proposal we have made to simplify and speed up merge operations: > State resolution v2 uses certain graph algorithms, which can result in at least linear processing time for the number of state events in a room’s DAG, creating a significant load on servers. > > The goal of this issue is to discuss and develop changes to state resolution to achieve O(n log ⁡ n) total processing time when handling a room with *n* state events (i.e., O(log ⁡ n) on average) in realistic scenarios, while maintaining a good user experience. > > The approach described below is closer to state resolution v1 but seeks to address state resets in a different way. For more detail, you can read our proposal on the Matrix spec tracker: [Make state resolution faster](https://github.com/matrix-org/matrix-spec/issues/1922?ref=process-one.net). In simpler terms, we propose adding a version associated with each `event_id` to simplify conflict management and introduce a heuristic that skips traversal of large parts of the graph. ## Impact of the Proposal From our initial assessment, in a very large room — such as one with 100,000 members — our approach could improve processing performance by 100x to 1000x, as the current processing cost scales with the number of users in the room. This improvement would enable smoother conversations, reduced lag, and more responsive interactions for end-users, while also reducing server infrastructure load and resource usage. While our primary goal is to improve performance in very large rooms, these changes benefit all users by reducing overall server load and improving processing times across various room sizes. We plan to implement this improvement in our own code to evaluate its real-world effectiveness while the Matrix team considers its potential value for the reference protocol. --- 1. For those who remember, a conversation in Matrix is similar to the collaborative editing protocol built on top of XMPP for the Google Wave platform. ### ejabberd 24.10 URL: https://www.process-one.net/blog/ejabberd-24-10/ Last updated: 2024-10-29T18:01:42.000Z We’re excited to announce ejabberd 24.10, a major release packed with substantial improvements and support for important extensions specified by the XMPP Standard Foundation (XSF). This release represents three months of focused development, bringing around 100 commits to the core repository alongside key updates in dependencies. The improvements span enhanced security and streamlined connectivity—all designed to make ejabberd more powerful and easier to use than ever. **Release Highlights:** - **[XEP-0288: Bidirectional Server-to-Server Connections](#bidi)** - **[XEP-0480: SASL Upgrade Tasks](#scram%5Fupgrade)** - **[IQ permission in privileged entities](#iqpermission)** - **[PubSub varied fixes](#pubsub)** - **[WebAdmin improvements](#webadmin)** If you are upgrading from a previous version, please note [minor changes in commands](#commands) and [two changes in hooks](#hooks). There are no configuration or SQL schema changes in this release. Below is a detailed breakdown of the new features, fixes, and enhancements: ## Support for XEP-0288: Bidirectional Server-to-Server Connections The new `mod_s2s_bidi` module introduces support for [XEP-0288: Bidirectional Server-to-Server Connections](https://xmpp.org/extensions/xep-0288.html?ref=process-one.net). This update removes the requirement for two connections per server pair in XMPP federations, allowing for more streamlined inter-server communications. However, for full compatibility, ejabberd can still connect to servers that do not support bidirectional connections, using two connections when necessary. The module is enabled by default in the sample configuration. ## Support for XEP-0480: SASL Upgrade Tasks The new `mod_scram_upgrade` module implements [XEP-0480: SASL Upgrade Tasks](https://xmpp.org/extensions/xep-0480.html?ref=process-one.net). Compatible clients can now automatically upgrade encrypted passwords to more secure formats, enhancing security with minimal user intervention. ## PubSub Service Improvements We’ve implemented six noteworthy fixes to improve PubSub functionality: - PEP notifications are sent only to owners when `+notify` ([3469a51](https://github.com/processone/ejabberd/commit/3469a51f5896ef96b2e53d61fcfd2163b92ad11a?ref=process-one.net)) - Non-delivery errors for locally generated notifications are now skipped ([d4b3095](https://github.com/processone/ejabberd/commit/d4b30957a384a54941cefc869cf6c3a04b2769bc?ref=process-one.net)) - Fix default node config parsing ([b439929](https://github.com/processone/ejabberd/commit/b4399291efd86f06d2d2883f5fc2c66e9d39a27b?ref=process-one.net)) - Fix merging of default node options ([ca54f81](https://github.com/processone/ejabberd/commit/ca54f81f58f63646104845758d9bb5e661d8da84?ref=process-one.net)) - Fix choice of node config defaults ([a9583b4](https://github.com/processone/ejabberd/commit/a9583b43c37c38accfe06dc44e9f634cd8f92498?ref=process-one.net)) - Fall back to default plugin options ([36187e0](https://github.com/processone/ejabberd/commit/36187e07d0652e5c2f891f48cdf958b872a70f5d?ref=process-one.net)) ## IQ permission for privileged entities The [mod\_privilege](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fprivilege) module now supports [IQ permission](https://xmpp.org/extensions/xep-0356.html?ref=process-one.net#iq) based on version 0.4 of [XEP-0356: Privileged Entity](https://xmpp.org/extensions/xep-0356.html?ref=process-one.net). See [#3889](https://github.com/processone/ejabberd/issues/3889?ref=process-one.net) for details. This feature is especially useful for XMPP gateways using the [Slidge](https://sr.ht/~nicoco/slidge/?ref=process-one.net) library. ## WebAdmin improvements [ejabberd 24.06](https://www.process-one.net/ejabberd-24-06/) release laid the foundation for a more streamlined WebAdmin interface, reusing existing commands instead of using specific code, with a possibly different logic. This major change allows developers to add new pages very fast, just by calling existing commands. It also allows administrators to use the same commands than in `ejabberdctl` or any other [command frontend](https://docs.ejabberd.im/developer/ejabberd-api/?ref=process-one.net#understanding-ejabberd-commands). As a result, many new pages and content were added. Building on that, the 24.10 update introduces MAM (Message Archive Management) support, allowing administrators to view message counts, remove all MAM messages, or only for a specific contact, and also view the MAM Archive directly from WebAdmin. ![webadmin-mam-screen](https://www.process-one.net/content/images/2024/10/ejabberd-24.10-webadmin-1.png) Additionally, WebAdmin now hides pages related to modules that are disabled, preventing unnecessary options from displaying. This affects mod\_last, mod\_mam, mod\_offline, mod\_privacy, mod\_private, mod\_roster, mod\_vcard. ## Fixes in commands - `set_presence`: Now returns an error when the session is not found. - `send_direct_invitation`: Improved handling of malformed JIDs. - `update`: Fix command output. So far, `ejabberd_update:update/0` returned the return value of `release_handler_1:eval_script/1`. That function returns the list of updated but unpurged modules, i.e., modules where one or more processes are still running an old version of the code. Since commit `5a34020d23f455f80a144bcb0d8ee94770c0dbb1`, the ejabberd `update` command assumes that value to be the list of updated modules instead. As that seems more useful, modify `ejabberd_update:update/0` accordingly. This fixes the `update` command output. - `get_mam_count`: New command to retrieve the number of archived messages for a specific account. ## Changes in hooks Two key changes in hooks: - New `check_register_user` hook in `ejabberd_auth.erl` to allow blocking account registration when a tombstone exists. - Modified `room_destroyed` hook in `mod_muc_room.erl`. Until now the hook passed as arguments: `LServer, Room, Host`. Now it passes: `LServer, Room, Host, Persistent` That new `Persistent` argument passes the room `persistent` option, required by mod\_tombstones because only persistent rooms should generate a tombstone, temporary ones should not. And the `persistent` option should not be completely overwritten, as we must still known its real value even when room is being destroyed. ## Log Erlang/OTP and Elixir versions During server start, ejabberd now shows in the log not only its version number, but also the Erlang/OTP and Elixir versions being used. This will help the administrator to determine what software versions are being used, which is specially useful when investigating some problem, and explaining it to other people for help. The `ejabberd.log` file now looks like this: ``` ... 2024-10-22 13:47:05.424 [info] Creating Mnesia disc_only table 'oauth_token' 2024-10-22 13:47:05.427 [info] Creating Mnesia disc table 'oauth_client' 2024-10-22 13:47:05.455 [info] Waiting for Mnesia synchronization to complete 2024-10-22 13:47:05.591 [info] ejabberd 24.10 is started in the node :ejabberd@localhost in 1.93s 2024-10-22 13:47:05.606 [info] Elixir 1.16.3 (compiled with Erlang/OTP 26) 2024-10-22 13:47:05.606 [info] Erlang/OTP 26 [erts-14.2.5.4] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [jit:ns] 2024-10-22 13:47:05.608 [info] Start accepting TCP connections at 127.0.0.1:7777 for :mod_proxy65_stream 2024-10-22 13:47:05.608 [info] Start accepting UDP connections at [::]:3478 for :ejabberd_stun 2024-10-22 13:47:05.608 [info] Start accepting TCP connections at [::]:1883 for :mod_mqtt 2024-10-22 13:47:05.608 [info] Start accepting TCP connections at [::]:5280 for :ejabberd_http ... ``` ## Brand new ProcessOne and ejabberd web sites We’re excited to unveil the redesigned ProcessOne website, crafted to better showcase our expertise in large-scale messaging across XMPP, MQTT, Matrix, and more. This update highlights our core mission of delivering scalable, reliable messaging solutions, with a fresh layout and streamlined structure that reflect our cutting-edge work in the field. You now get a cleaner [ejabberd page](https://www.process-one.net/ejabberd/), offering quick access to important URLs for downloads, blog posts, and documentation. Behind the scenes, we’ve transitioned from WordPress to Ghost, a move inspired by its efficient, user-friendly authoring tools and long-term maintainability. All previous blog content has been preserved, and with this new setup, we’re poised to deliver more frequent updates on messaging, XMPP, ejabberd, and related topics. We welcome your feedback—join us on our new site to share your thoughts, or let us know about any issue or broken link! ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Holger Weiß](https://github.com/weiss?ref=process-one.net) for PubSub and other fixes - [Michael Slezak](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net) for mix release fix - [Guus der Kinderen](https://github.com/guusdk?ref=process-one.net) for the XMPP Interop tests - [Sketch6580](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net), updated the Chinese translation - [Wellington Uemura](https://github.com/wtuemura?ref=process-one.net), updated the Portuguese (Brazil) translation - [Ermete Melchiorre](https://github.com/sudcapitano?ref=process-one.net), updated the Italian translation - [Mr. EddX](https://github.com/MrEddX?ref=process-one.net), updated the Bulgarian translation And also to all the people contributing in the ejabberd chatroom, issue tracker... ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get MUC support in `mod_unread`. ejabberd keeps a counter of unread messages per conversation using the `mod_unread` module. This now also works in MUC rooms: each user can retrieve the number of unread messages in each of their rooms. ## ChangeLog This is a more detailed list of changes in this ejabberd release: #### Miscelanea - `ejabberd_c2s`: Optionally allow unencrypted SASL2 - `ejabberd_system_monitor`: Handle call by `gen_event:swap_handler` ([#4233](https://github.com/processone/ejabberd/issues/4233?ref=process-one.net)) - `ejabberd_http_ws`: Remove support for old websocket connection protocol - `ejabberd_stun`: Omit `auth_realm` log message - `ext_mod`: Handle `info` message when contrib module transfers table ownership - `mod_block_strangers`: Add feature announcement to disco-info ([#4039](https://github.com/processone/ejabberd/issues/4039?ref=process-one.net)) - `mod_mam`: Advertise XEP-0424 feature in server disco-info ([#3340](https://github.com/processone/ejabberd/issues/3340?ref=process-one.net)) - `mod_muc_admin`: Better handling of malformed jids in `send_direct_invitation` command - `mod_muc_rtbl`: Fix call to `gen_server:stop` ([#4260](https://github.com/processone/ejabberd/issues/4260?ref=process-one.net)) - `mod_privilege`: Support "IQ permission" from XEP-0356 0.4.1 ([#3889](https://github.com/processone/ejabberd/issues/3889?ref=process-one.net)) - `mod_pubsub`: Don't blindly echo PEP notification - `mod_pubsub`: Skip non-delivery errors for local pubsub generated notifications - `mod_pubsub`: Fall back to default plugin options - `mod_pubsub`: Fix choice of node config defaults - `mod_pubsub`: Fix merging of default node options - `mod_pubsub`: Fix default node config parsing - `mod_register`: Support to block IPs in a vhost using `append_host_config` ([#4038](https://github.com/processone/ejabberd/issues/4038?ref=process-one.net)) - `mod_s2s_bidi`: Add support for S2S Bidirectional - `mod_scram_upgrade`: Add support for SCRAM upgrade tasks - `mod_vcard`: Return error stanza when storage doesn't support vcard update ([#4266](https://github.com/processone/ejabberd/issues/4266?ref=process-one.net)) - `mod_vcard`: Return explicit error stanza when user attempts to modify other's vcard - Minor improvements to support `mod_tombstones` (#2456) - Update `fast_xml` to use `use_maps` and remove obsolete elixir files - Update `fast_tls` and `xmpp` to improve s2s fallback for invalid direct tls connections - `make-binaries`: Bump dependency versions: Elixir 1.17.2, OpenSSL 3.3.2, ... #### Administration - `ejabberdctl`: If `ERLANG_NODE` lacks host, add hostname ([#4288](https://github.com/processone/ejabberd/issues/4288?ref=process-one.net)) - `ejabberd_app`: At server start, log Erlang and Elixir versions - MySQL: Fix column type in the schema update of `archive` table in schema update #### Commands API - `get_mam_count`: New command to get number of archived messages for an account - `set_presence`: Return error when session not found - `update`: Fix command output - Add `mam` and `offline` tags to the related purge commands #### Code Quality - Fix warnings about unused macro definitions reported by Erlang LS - Fix Elvis report: Fix dollar space syntax - Fix Elvis report: Remove spaces in weird places - Fix Elvis report: Don't use ignored variables - Fix Elvis report: Remove trailing whitespace characters - Define the types of options that `opt_type.sh` cannot derive automatically - `ejabberd_http_ws`: Fix dialyzer warnings - `mod_matrix_gw`: Remove useless option `persist` - `mod_privilege`: Replace `try...catch` with a clean alternative #### Development Help - `elvis.config`: Fix file syntax, set vim mode, disable many tests - `erlang_ls.config`: Let it find paths, update to Erlang 26, enable crossref - `hooks_deps`: Hide false-positive warnings about `gen_mod` - `Makefile`: Add support for `make elvis` when using rebar3 - `.vscode/launch.json`: Experimental support for debugging with Neovim - CI: Add Elvis tests - CI: Add XMPP Interop tests - Runtime: Cache hex.pm archive from rebar3 and mix #### Documentation - Add links in top-level options documentation to their Docs website sections - Document which SQL servers can really use `update_sql_schema` - Improve documentation of `ldap_servers` and `ldap_backups` options ([#3977](https://github.com/processone/ejabberd/issues/3977?ref=process-one.net)) - `mod_register`: Document behavior when `access` is set to `none` ([#4078](https://github.com/processone/ejabberd/issues/4078?ref=process-one.net)) #### Elixir - Handle case when elixir support is enabled but not available - Start ExSync manually to ensure it's started if (and only if) Relive - `mix.exs`: Fix `mix release` error: `logger` being regular and included application ([#4265](https://github.com/processone/ejabberd/issues/4265?ref=process-one.net)) - `mix.exs`: Remove from `extra_applications` the apps already defined in `deps` ([#4265](https://github.com/processone/ejabberd/issues/4265?ref=process-one.net)) #### WebAdmin - Add links in user page to offline and roster pages - Add new "MAM Archive" page to webadmin - Improve many pages to handle when modules are disabled - `mod_admin_extra`: Move some webadmin pages to their modules ### Full Changelog [https://github.com/processone/ejabberd/compare/24.07...24.10](https://github.com/processone/ejabberd/compare/24.07...24.10?ref=process-one.net) ## ejabberd 24.10 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you've found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### ProcessOne Unveils New Website URL: https://www.process-one.net/blog/processone-unveils-new-website/ Last updated: 2024-10-23T08:16:06.000Z We’re excited to announce the relaunch of our website, designed to better showcase our expertise in large-scale messaging solutions, highlighting our full spectrum of supported protocols—from XMPP to MQTT and Matrix. This reflects our core strength: delivering reliable messaging at scale. The last major redesign was back in October 2017, so this update was long overdue. As we say farewell to the old design, here’s a screenshot of the previous version to commemorate the journey so far. ![](https://www.process-one.net/content/images/2024/10/Goodbye-ProcessOne-site-from-2017-1.png) In addition to refreshing the layout and structure, we’ve made a significant change under the hood by migrating from WordPress to Ghost. After using Ghost for my personal blog and being thoroughly impressed, we knew it was the right choice for ProcessOne. The new platform offers not only long-term maintainability but also a much more streamlined, enjoyable day-to-day experience, thanks to its faster and more efficient authoring tools. All of our previous blog content has been successfully migrated, and we’re now in a great position to deliver more frequent updates on topics such as messaging, XMPP, ejabberd, MQTT, and Matrix. Stay tuned for exciting new posts! We’d love to hear your feedback and suggestions on what topics you’d like us to cover next. To join the conversation, simply create an account on our site and share your thoughts. ### Easily Monitor Push Notifications with Fluux ejabberd Managed Service URL: https://www.process-one.net/blog/check-your-push-logs-on-fluux-io/ Last updated: 2024-10-21T13:55:39.000Z Good news! You can now monitor your push notifications directly through your [fluux.io](https://fluux.io/?ref=process-one.net) console, offering better visibility into the status and delivery of messages to your users. ## How to Access Push Logs To start, navigate to the **Push Apps** list in your Fluux.io dashboard (see [WebPush support](https://www.process-one.net/blog/webpush-support-on-your-fluux-io-instance/) for instructions). From there, you can access the *Push Logs* section, which provides detailed insights into the push notifications sent from your server. ![](https://www.process-one.net/wp-content/uploads/2024/10/Screenshot-2024-10-07-at-18.22.47-1024x401.png) ## Tracking Push Notification Status Once a push notification is triggered, you can check its status through the push gateway. This feature offers critical information about your users’ devices and the delivery process, enabling you to troubleshoot common issues more efficiently. For example, you may encounter: - **BadToken:** This indicates that something went wrong during the device registration process, rendering the token invalid. - **Token Gone:** This means the device’s registration has been canceled by the push provider, for example, because the app has been uninstalled, the device replaced or the token rotated. In both scenarios, your client application will need to re-register the user’s device to ensure successful notifications going forward. ![](https://www.process-one.net/wp-content/uploads/2024/10/Screenshot-2024-10-07-at-18.49.18-copy-1024x401.png) ## Debugging Delivery to User Devices In addition to error tracking, you’ll also be able to see when a push has been successfully delivered to the gateway. If you’re working with Apple’s push notifications, APNs sandbox entries will include an *apns-uniq-id*. This identifier allows you to further trace the delivery of messages to the user’s device via the [Apple Cloud dashboard](https://icloud.developer.apple.com/dashboard?ref=process-one.net) \-— an handy tool for those deep-dive debugging sessions. ### Matrix and XMPP: Thoughts on Improving Messaging Protocols – Part 1 URL: https://www.process-one.net/blog/matrix-and-xmpp-thoughts-on-improving-messaging-protocols-part-1/ Last updated: 2024-11-05T13:56:59.000Z We began with XMPP (eXtensible Messaging and Presence Protocol), but the need for interoperability and support for a variety of use cases led us to implement additional protocols. Our stack now supports: - **XMPP (eXtensible Messaging and Presence Protocol):** A robust, highly scalable, and flexible protocol for real-time messaging. - **MQTT (Message Queuing Telemetry Transport):** The standard for IoT messaging, ideal for lightweight communication between devices. - **SIP (Session Initiation Protocol):** A widely used standard for voice-over-IP (VoIP) communications. - **Matrix:** A decentralized protocol for secure, real-time communication. ## A Distributed Protocol That Replicates Data Across Federated Servers This brings me to the topic of Matrix. Matrix is designed not just to be federated but also distributed. While it uses the term “decentralized,” I find this slightly misleading. A federated protocol is inherently decentralized, as it allows users across different domains to communicate–think email, XMPP, and Matrix itself. What truly sets Matrix apart from XMPP is its data distribution model. Matrix is distributed because it aims to ensure that all participating nodes in a conversation have a copy of that conversation, typically in end-to-end encrypted form. This ensures high availability: if the primary node hosting a conversation becomes unavailable, the conversation can continue on another node. In Matrix, a conversation is represented as a graph, a replicated document containing all events related to a group discussion. You can think of each conversation as a mini-blockchain, except that instead of forming a chain, the events create a graph. ## Resource Penalty: Computing and Storage As with any design decision, there are trade-offs. In the case of Matrix, this comes with a performance penalty. Since conversations are replicated across nodes, the protocol performs merge operations to ensure consistency between the replicated data. The higher the traffic, the greater the cost of these merge operations, which adds CPU load on both the Matrix node and its database. Additionally, there is a significant cost in terms of storage. If the Matrix network were to scale massively, with many nodes and conversations, it would encounter the same growth challenges as blockchain protocols. Each node must store a copy of the conversation, and the amount of replication depends on the number of conversations and nodes globally. As these numbers grow, so does the replication factor. ## Comparison with XMPP XMPP, on the other hand, is event-based rather than document-based. It processes and distributes events in the order they arrive without attempting to merge conversation histories. This simpler approach avoids the replication of group chat data across federated nodes, but it comes with some limitations. Here’s how XMPP mitigates these limitations: - **One-on-One Conversations:** Each user’s messages are archived on their server, keeping the replication factor under control (usually limited to two copies). - **Group Chats:** If a chatroom goes down, the conversation becomes unavailable for both local and remote users. However, XMPP has strategies to reduce the need for data replication. Several servers implement clustering, making it possible to upgrade the service node by node. If one node is taken down (for maintenance, for instance), another node can take over the management of the chatroom. - **Hot Code Upgrades:** Some servers, like ejabberd, allow hot code upgrades, which means minor updates can be applied without shutting down the node, minimizing downtime and the need for data replication. - **Message Archiving for MUC Rooms:** Some servers offer message archiving for multi-user chat (MUC) rooms, but also allows users to store on their local server recent chat history in select MUC for future reference. - **Cluster Replication (ejabberd Business Edition):** Chatrooms can be replicated within a cluster, ensuring they remain available even if a node crashes. Thanks to the typically high uptime of XMPP servers, especially for clustered services, intermittent availability of servers in the network hasn’t posed a significant issue, so large-scale data replication hasn’t been a necessity. ## What’s Next for XMPP? This comparison suggests potential improvements for XMPP. Could XMPP benefit from an optional feature to address the centralized nature of chatrooms? Possibly. What if there were a caching and resynchronization protocol for multi-user chatrooms across different servers? This could enhance the robustness of the federation without the storage burden of full content replication, offering the best of both worlds. ## What’s Next for Matrix? Matrix, by design, comes with trade-offs. One of its key goals is to resist censorship, which is vital in certain situations and countries. That’s why we believe it is worth trying to improve the Matrix protocol to address those use cases. There’s still room to optimize the protocol, specifically by reducing the cost of running a distributed data store. We plan to propose and implement improvements on how merge operations work to make Matrix more efficient. I’ll share our proposals in the next article: [Thoughts on Improving Messaging Protocols — Part 2, Matrix](https://www.process-one.net/blog/thoughts-on-improving-messaging-protocols-part-2-matrix/). — *As always, this is an open discussion, and I’d be happy to dive deeper into these topics if you’re interested.* *Feedback received:* - *2024-10-25: I had envisioned the concept of automatic caching for MUC messages. However, there is an existing XEP that defines the behavior for federated MUC in XMPP:* [*XEP-0289: Federated MUC for Constrained Environments*](https://xmpp.org/extensions/xep-0289.html?ref=process-one.net)*. I am not aware of any implementations of this yet, but it’s a topic we are interested in exploring.* ### ejabberd 24.07 URL: https://www.process-one.net/blog/ejabberd-24-07/ Last updated: 2024-10-10T14:33:40.000Z If you upgrade ejabberd from a previous release, please check the [WebAdmin Config Changes](https://www.process-one.net/blog/ejabberd-24-07/#webadmin-config). A more detailed explanation of those topics and other features: ## WebAdmin API permissions configuration The ejabberd 24.06 release notes announced the [Improved WebAdmin with commands usage](https://www.process-one.net/blog/ejabberd-24-06/#webadmin-commands), and mentioned some [api\_permissions configuration details](https://www.process-one.net/blog/ejabberd-24-06/#webadmin-config), but it was not explicit enough about this fact: with the default ejabberd configuration, an admin was allowed to log in to WebAdmin from any machine, but was only allowed to run commands from the loopback IP address! The WebAdmin showed the page sections, but they were all empty. In addition, there was a bug that showed similar symptoms when entering the WebAdmin from one host and then logging in as an account in another host. Both problems and their solutions are described in [#4249](https://github.com/processone/ejabberd/issues/4249?ref=process-one.net). Please update your configuration accordingly, adding permission from web admin to execute all commands to accounts logged in with admin privilege: ```yaml api_permissions: "webadmin commands": from: ejabberd_web_admin who: admin what: "*" ``` Of course you can customize that access as much as you want: only from specific IP addresses, only to certain accounts, only for specific commands… ## New option `update_sql_schema_timeout` The [new option update\_sql\_schema\_timeout](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#update%5Fsql%5Fschema%5Ftimeout) allows the [schema update process](https://www.process-one.net/blog/automatic-schema-update-in-ejabberd/) to use longer timeouts. The default value is set to 5 minutes. This also makes batch of schema updates to single table use transaction. This should help in not leaving table in inconsistent state if some update steps fail (unless you use MySQL where you can’t rollback changes to table schemas). ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Holger Weiß](https://github.com/weiss?ref=process-one.net) for several bugfixes - [Pouriya Jahanbakhsh](https://github.com/pouriya?ref=process-one.net) for hook subscribers support - [Michael Slezak](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net) for Elixir logging fix - [heyanyanchina123](https://github.com/heyanyanchina123?ref=process-one.net), fixed `mysql.sql` archive origin\_id - [Sketch6580](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net), updated the Chinese translation - [Ermete Melchiorre](https://github.com/sudcapitano?ref=process-one.net), updated the Italian translation - [Wellington Uemura](https://github.com/wtuemura?ref=process-one.net), updated the Portuguese (Brazil) And also to all the people contributing in the ejabberd chatroom, issue tracker… ## ChangeLog This is a more detailed list of changes in this ejabberd release: #### Core - `ejabberd_options`: Add trailing `@` to `@VERSION@` parsing - `mod_http_api`: Fix problem parsing tuples when using OTP 27 json library ([#4242](https://github.com/processone/ejabberd/issues/4242?ref=process-one.net)) - `mod_http_api`: Restore args conversion of `{"k":"v"}` to tuple lists - `mod_matrix_gw`: Add misc:json\_encode\_With\_kv\_lists and use it in matrix sign function - `mod_muc`: Output `muc#roominfo_avatarhash` in room disco info as per updated XEP-0486 ([#4234](https://github.com/processone/ejabberd/issues/4234?ref=process-one.net)) - `mod_muc`: Improve cross version handling of muc retractions - `node_pep`: Add missing feature `item-ids` to node\_pep - `mod_register`: Send welcome message as `chat` too ([#4246](https://github.com/processone/ejabberd/issues/4246?ref=process-one.net)) - `ejabberd_hooks`: Support for ejabberd hook subscribers, useful for [mod\_prometheus](https://github.com/processone/ejabberd-contrib/tree/master/mod%5Fprometheus?ref=process-one.net) - `ejabberd.app`: Don’t add `iex` to included\_applications - `make-installers`: Fix path in scripts in regular user install ([#4258](https://github.com/processone/ejabberd/issues/4258?ref=process-one.net)) - Test: New tests for API commands #### Documentation - `mod_matrix_gw`: Fix `matrix_id_as_jid` option documentation - `mod_register`: Add example configuration of `welcome_message` option - `mix.exs`: Add ejabberd example config files to the hex package - Update `CODE_OF_CONDUCT.md` #### ext\_mod - Fetch dependencies from hex.pm when mix is available - files\_to\_path is deprecated, use compile\_to\_path - Compile all Elixir files in a library with one function call - Improve error result when problem compiling elixir file - Handle case when contrib module has no `*.ex` and no `*.erl` - `mix.exs`: Include Elixir’s Logger in the OTP release, useful for [mod\_libcluster](https://github.com/processone/ejabberd-contrib/tree/master/mod%5Flibcluster?ref=process-one.net) #### Logs - Print message when starting ejabberd application fails - Use error\_logger when printing startup failure message - Use proper format depending on the formatter ([#4256](https://github.com/processone/ejabberd/issues/4256?ref=process-one.net)) #### SQL - Add option `update_sql_schema_timeout` to allow schema update use longer timeouts - Add ability to specify custom timeout for sql operations - Allow to configure number of restart in `sql_transaction()` - Make sql query in testsuite compatible with pg9.1 - In `mysql.sql`, fix update instructions for the `archive` table, `origin_id` column ([#4259](https://github.com/processone/ejabberd/issues/4259?ref=process-one.net)) #### WebAdmin - `ejabberd.yml.example`: Add `api_permissions` group for webadmin ([#4249](https://github.com/processone/ejabberd/issues/4249?ref=process-one.net)) - Don’t use host from url in webadmin, prefer host used for authentication - Fix number of accounts shown in the online-users page - Fix crash when viewing old shared roster groups ([#4245](https://github.com/processone/ejabberd/issues/4245?ref=process-one.net)) - Support groupid with spaces when making shared roster result ([#4245](https://github.com/processone/ejabberd/issues/4245?ref=process-one.net)) ### Full Changelog [https://github.com/processone/ejabberd/compare/24.06…24.07](https://github.com/processone/ejabberd/compare/24.06...24.07?ref=process-one.net) ## ejabberd 24.07 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you’ve found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Breaking Down the Costs of Large Messaging Services URL: https://www.process-one.net/blog/breaking-down-the-costs-of-large-messaging-services/ Last updated: 2024-09-16T09:41:57.000Z It estimates that the cost to operate Signal messaging will reach 50 million dollars per year in 2025. [Privacy is Priceless, but Signal is Expensive](https://signal.org/blog/signal-is-expensive/?ref=process-one.net) As of the end of 2023, the cost breakdown for running a large messaging platform like Signal was as follows: - **Storage:** $1.3 million per year (9.3%). It is interesting to note that Signal does not store message history on the server. Message history is stored on the client. - **Servers:** $2.9 million per year (20.7%). Cost of cloud servers to support the messaging service. - **Registration Fees:** $6 million per year (42.9%). This is the cost required to validate phone numbers and perform other validations. - **Total Bandwidth:** $2.8 million per year (20.0%). - **Additional Services:** $700,000 per year (5.0%). Uptime monitoring, outage alerts, redundant capacity for disaster recovery purposes, maintenance contracts, etc. Infrastructure Costs (as of November 2023): Approximately $14 million per year, to support between 40 and 50 million monthly active users. And this is just for the infrastructure costs ! You need to add all the associated costs to operate an organization employing more than 50 people. This article is interesting on several accounts: - If you want to run a messaging platform at scale, we can help you with that, but be sure to properly assess your operating costs as well. **Ensure your ambition aligns with your business model.** - This also shows the **impact of the centralized approach vs a federated model**. With a centralized model, the organization running the platform has to assume all the costs for operating the platform. In a federated model like XMPP, the costs can be split across the whole network. The technical design of a messaging service significantly impacts the operational costs of the platform. Therefore, it’s crucial to make business model and technical choices simultaneously and be flexible to adapt to platform growth, as they are two sides of the same coin. Aligning these decisions ensures that both financial sustainability and technical feasibility are achieved. ### ejabberd 24.06 URL: https://www.process-one.net/blog/ejabberd-24-06/ Last updated: 2024-09-16T09:45:43.000Z This new ejabberd 24.06 includes four months of work, close to 200 commits, including several minor improvements in the core ejabberd, and a lot of improvements in the administrative parts of ejabberd, like the WebAdmin and new API commands. #### Brief summary - **Webadmin rework** - **Improved documentation** - **Architecture and API improvements** If you upgrade ejabberd from a previous release, please review those changes: - [SQL Schema Changes](https://www.process-one.net/blog/ejabberd-24-06/#sql) - [Commands Changed in API v2](https://www.process-one.net/blog/ejabberd-24-06/#apiv2) - [WebAdmin Hook Changes](https://www.process-one.net/blog/ejabberd-24-06/#webadmin-hooks) A more detailed explanation of those topics and other features: ## Support for Erlang/OTP 27 and Elixir 1.17 ejabberd support for Erlang/OTP 27.0 has been improved. In this sense, when using Erlang/OTP 27, the `jiffy` dependency is not needed, as an equivalent feature is already included in OTP. The lowest supported Erlang/OTP version continues being 20.0, and the recommendation is using 26.2, which is in fact the one included in the binary installers and container images. Regarding Elixir, the new 1.17 works correctly. The lowest Elixir supported version is 1.10.3… but in order to benefit from all the ejabberd features, it is highly recommended to use Elixir 1.13.4 or higher with Erlang/OTP 23.0 or higher. ## SQL schema changes There are no changes in the SQL schemas in this release. Notice that ejabberd can take care to update your MySQL, PostgreSQL and SQLite database schema if you enable the [update\_sql\_schema](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#update%5Fsql%5Fschema) toplevel option. That feature was introduced for beta-testing in [ejabberd 23.10](https://www.process-one.net/blog/ejabberd-23-10/) and announced in the blog post [Automatic schema update in ejabberd](https://www.process-one.net/blog/automatic-schema-update-in-ejabberd/). Starting in this ejabberd 24.06, the `update_sql_schema` feature is considered stable and the option is enabled by default! ## UNIX Socket Domain The [sql\_server](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#sql%5Fserver) top-level option now accepts the path to a unix socket domain, expressed as `"unix:/path/to/socket"`, as long as you are using mysql or pgsql in the option `sql_type`. ## Commands changed in API v2 This ejabberd 24.06 release introduces ejabberd Commands API v2\. You can continue using API v1; or if you want to update your API client to use APIv2, those are the commands that changed and you may need to update in your client: Support for banning an account has been improved in API v2: – [ban\_account](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#ban%5Faccount) stores the ban information in the account XML private storage, so that command requires `mod_private` to be enabled – [get\_ban\_details](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get%5Fban%5Fdetails) shows information about the account banning, if any. – [unban\_account](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#unban%5Faccount) performs the reverse operation, getting the account to its previous status. The result value of those two commands was modified to allow their usage in WebAdmin: – [kick\_user](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#kick%5Fuser) instead of returning an integer, it returns a restuple. – [rooms\_empty\_destroy](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#rooms%5Fempty%5Fdestroy) instead of returning a list of rooms that were destroyed, it returns a `restuple`. As a side note, this command has been improved, but this change doesn’t affect the API: – [join\_cluster](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#join%5Fcluster) has been improved to work not only with the `ejabberdctl` command line script, but also with any other command frontend (`mod_http_api`, `ejabberd_xmlrpc`, `ejabberd_web_admin`, …). ## New commands Several new commands have been added, specially useful to generate WebAdmin pages: - [get\_roster\_count](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get%5Froster%5Fcount) - [get\_master](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get%5Fmaster) - [list\_cluster\_detailed](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#list%5Fcluster%5Fdetailed) - [srg\_add](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#srg%5Fadd) - [srg\_add\_displayed](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#srg%5Fadd%5Fdisplayed) - [srg\_del\_displayed](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#srg%5Fdel%5Fdisplayed) - [srg\_get\_displayed](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#srg%5Fget%5Fdisplayed) - [srg\_set\_info](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#srg%5Fset%5Finfo) - [join\_cluster\_here](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#join%5Fcluster%5Fhere) ## Improved WebAdmin with commands usage ![WebAdmin screenshot](https://www.process-one.net/wp-content/uploads/2024/06/webadmin2.png) 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. This release includes a set of functions (`make_command/2` and `/4`, `make_command_raw_value/3`, `make_table/2` and `/4`) to use all those commands to generate HTML content in the ejabberd WebAdmin: instead of writing again erlang code to perform those operations and then write code to format it and display as HTML… let’s have some frontend functions to call the command and generate the HTML content. With that new feature, writing content for WebAdmin is much easier if a command for that task already exists. In this sense, most of the ejabberd WebAdmin pages have been rewritten to use the new `make_command` feature, many new pages are added using the existing commands. Also a few commands and pages are added to manage Shared Roster Groups. ![WebAdmin screenshot](https://www.process-one.net/wp-content/uploads/2024/06/webadmin1.png) ## WebAdmin commands permissions configuration Most WebAdmin pages use commands to generate the content, and access to those commands can be restricted using the [api\_permissions toplevel option](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#api%5Fpermissions). The default `ejabberd.yml` configuration file already defines `"admin access"` that allows access from loopback IP address and accounts in the `admin` ACL to execute all commands except `stop` and `start`. So, no changes are required in the default configuration file to use the upgrade WebAdmin pages. Now `ejabberd_web_admin` is another valid command frontend that can be specified in the `from` section. You can define fine-grained restrictions for accounts in WebAdmin, for example: ```yaml api_permissions: "webadmin commands": from: - ejabberd_web_admin who: admin what: - "*" - "![tag:oauth]" ``` ## WebAdmin hook changes There are several changes in WebAdmin hooks that now provide the whole HTTP request instead of only some of its elements. You can update your code easily, see: - `webadmin_page_node`: instead of Path, Query and Lang, gets Request ```diff -webadmin_page_node(Acc, Node, Path, Query, Lang) -> +webadmin_page_node(Acc, Node, #request{path = Path, q = Query, lang = Lang}) -> ``` - `webadmin_page_hostnode`: instead of Path, Query and Lang gets Request ```diff -webadmin_page_hostnode(Acc, Host, Node, Path, Query, Lang) -> +webadmin_page_hostnode(Acc, Host, Node, #request{path = Path, q = Query, lang = Lang}) -> ``` - `webadmin_user`: instead of just the Lang, gets the whole Request ```diff -webadmin_user(Acc, User, Server, Lang) -> +webadmin_user(Acc, User, Server, #request{lang = Lang}) -> ``` - `webadmin_menu_hostuser`: new hook added: ```diff +webadmin_menu_hostuser(Acc, Host, Username, Lang) -> ``` - `webadmin_page_hostuser`: new hook added: ```diff +webadmin_page_hostuser(Acc, Host, Username, Request) -> ``` ## `internal` command tag and `any` argument/result During the development of the WebAdmin commands feature, it was noticed the necessity to define some commands that will be used by WebAdmin (or maybe also by other ejabberd code), but should NOT be accessed by command frontends (like `ejabberdctl`, `mod_http_api`, `ejabberd_xmlrpc`). Such commands are identified because they have the `internal` tag. Those commands can use any arbitrarily-formatted arguments/results, defined as `any` in the command. ## Experimental `make format` and `indent` If you use Emacs with `erlang-mode`, Vim with some Erlang indenter, VSCode, … they indent erlang code more or less similarly, but sometimes have some minor differences. The new `make format` uses [rebar3\_format](https://github.com/AdRoll/rebar3%5Fformat?ref=process-one.net) to format and indent files, with those restrictions: - Only formats a file if it contains a line with this string, and formats only starting in a line with `@format-begin` - Formatting can be disabled later in the file by adding another line that contains `@format-end` - Furthermore, it is later possible to enable formatting again in the same file, in case there is another piece of the file that should be automatically formatted. Alternatively, the new `make indent` indents files using Emacs, it also replaces tabs with blankspaces and removes ending spaces. It can only indent one piece of code per file, the lines that finds between: ```erlang %% @indent-begin ... %% @indent-end ``` ## New MUC room logging hooks `mod_muc_room` now uses hooks instead of function calls to `mod_muc_log`, see [#4191](https://github.com/processone/ejabberd/issues/4191?ref=process-one.net). The new hooks available, in case you want to write an ejabberd module that logs MUC room messages: - `muc_log_check_access_log(Acc, Host, From)` - `muc_log_get_url(Acc, StateData)` - `muc_log_add(Host, Type, Data, RoomJid, Opts)` ## Support for code automatic update When running ejabberd in an interactive development shell started using `relive`, it automatically compiles and reloads the source code when you modify a source code file. How to use this: - Compile ejabberd with Rebar3 (or Mix) - Start ejabberd with `make relive` - Edit some ejabberd source code file and save it - [Sync](https://github.com/rustyio/sync?ref=process-one.net) (or [ExSync](https://github.com/falood/exsync?ref=process-one.net)) will compile and reload it automatically Rebar3 notes: - To ensure Sync doesn’t act on dependencies that would produce many garbage log lines, the `src_dirs` option is used. However, now it only works if the parent directory is named “ejabberd” - Sync requires [at least Erlang/OTP 21](https://www.erlang.org/patches/otp-21.0?ref=process-one.net), which introduced the new try-catch syntax to retrieve the stacktrace Mix note: - ExSync depends on [FileSystem library](https://github.com/falood/file%5Fsystem?ref=process-one.net#system-support), which requires inotify-tools ## ejabberd Docs now using MkDocs Several changes in ejabberd source code were done to produce markdown suitable for the new [ejabberd Docs](https://docs.ejabberd.im/?ref=process-one.net) site, as announced two months ago: [ejabberd Docs now using MkDocs](https://www.process-one.net/blog/ejabberd-docs-now-using-mkdocs/) ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Holger Weiß](https://github.com/weiss?ref=process-one.net) for several bugfixes - [Sketch6580](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net), updated the Chinese translation - [Nautilusx](https://hosted.weblate.org/user/nautilusx/?ref=process-one.net), updated the German translation - [Wojciech Teichert](https://github.com/wojtekt99?ref=process-one.net), updated the Polish translation And also to all the people contributing in the ejabberd chatroom, issue tracker… ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get: ### Pushy.me - Add support for the [Pushy.me](https://pushy.me/?ref=process-one.net) notification service for Mobile App ### Android Push - Add support for the [new FCMv1 API](https://firebase.google.com/docs/cloud-messaging/migrate-v1?ref=process-one.net) for Android Push - Improve errors reporting for wrong options in `mod_gcm` ### Apple Push - Update support for Apple Push API - Add support for p12 certificate in `mod_applepush` - Add `tls_verify` option to `mod_applepush` - Improve errors reporting for wrong options in `mod_applepush` ### Webpush - Properly initialize subject in Webpush ### Push - Add new API commands `setup_push`, `get_push_setup` and `delete_push_setup` for managing push setup, with support for Apple Push, Android Push, Pushy.me and Webpush/Webhook ## ChangeLog This is a more detailed list of changes in this ejabberd release: ### Core - `econf`: Add ability to use additional custom errors when parsing options - `ejabberd_logger`: Reloading configuration will update logger settings - `gen_mod`: Add support to specify a hook global, not vhost-specific - [mod\_configure](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fconfigure): Retract `Get User Password` command to update [XEP-0133](https://xmpp.org/extensions/xep-0133.html?ref=process-one.net) 1.3.0 - [mod\_conversejs](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fconversejs): Simplify support for `@HOST@` in `default_domain` option ([#4167](https://github.com/processone/ejabberd/issues/4167?ref=process-one.net)) - [mod\_mam](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmam): Document that [XEP-0441](https://xmpp.org/extensions/xep-0441.html?ref=process-one.net) is implemented as well - [mod\_mam](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmam): Update support for [XEP-0425](https://xmpp.org/extensions/xep-0425.html?ref=process-one.net) version 0.3.0, keep supporting 0.2.1 ([#4193](https://github.com/processone/ejabberd/issues/4193?ref=process-one.net)) - [mod\_matrix\_gw](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmatrix%5Fgw): Fix support for `@HOST@` in `matrix_domain` option ([#4167](https://github.com/processone/ejabberd/issues/4167?ref=process-one.net)) - [mod\_muc\_log](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmuc%5Flog): Hide join/leave lines, add method to show them - [mod\_muc\_log](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmuc%5Flog): Support `allowpm` introduced in 2bd61ab - [mod\_muc\_room](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmuc%5Froom): Use ejabberd hooks instead of function calls to `mod_muc_log` ([#4191](https://github.com/processone/ejabberd/issues/4191?ref=process-one.net)) - [mod\_private](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fprivate): Cope with bookmark decoding errors - [mod\_vcard\_xupdate](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fvcard%5Fxupdate): Send hash after avatar get set for first time - `prosody2ejabberd`: Handle the `approved` attribute. As feature isn’t implemented, discard it ([#4188](https://github.com/processone/ejabberd/issues/4188?ref=process-one.net)) ### SQL - [update\_sql\_schema](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#update%5Fsql%5Fschema): Enable this option by default - CI: Don’t load database schema files for mysql and pgsql - Support Unix Domain Socket with updated p1\_pgsql and p1\_mysql ([#3716](https://github.com/processone/ejabberd/issues/3716?ref=process-one.net)) - Fix handling of `mqtt_pub` table definition from `mysql.sql` and fix `should_update_schema/1` in `ejabberd_sql_schema.erl` - Don’t start sql connection pools for unknown hosts - Add `update_primary_key` command to sql schema updater - Fix crash running [export2sql](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#export2sql) when MAM enabled but MUC disabled - Improve detection of types in odbc ### Commands API - New ban commands use private storage to keep ban information ([#4201](https://github.com/processone/ejabberd/issues/4201?ref=process-one.net)) - [join\_cluster\_here](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#join%5Fcluster%5Fhere): New command to join a remote node into our local cluster - Don’t name integer and string results in API examples ([#4198](https://github.com/processone/ejabberd/issues/4198?ref=process-one.net)) - [get\_user\_subscriptions](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get%5Fuser%5Fsubscriptions): Fix validation of user field in that command - [mod\_admin\_extra](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fadmin%5Fextra): Handle case when `mod_private` is not enabled ([#4201](https://github.com/processone/ejabberd/issues/4201?ref=process-one.net)) - [mod\_muc\_admin](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmuc%5Fadmin): Improve validation of arguments in several commands ### Compile - `ejabberdctl`: Comment ERTS\_VSN variable when not used ([#4194](https://github.com/processone/ejabberd/issues/4194?ref=process-one.net)) - `ejabberdctl`: Fix iexlive after `make prod` when using Elixir - `ejabberdctl`: If `INET_DIST_INTERFACE` is IPv6, set required option ([#4189](https://github.com/processone/ejabberd/issues/4189?ref=process-one.net)) - `ejabberdctl`: Make native dynamic node names work when using fully qualified domain names - `rebar.config.script`: Support relaxed dependency version ([#4192](https://github.com/processone/ejabberd/issues/4192?ref=process-one.net)) - `rebar.config`: Update deps version to rebar3’s relaxed versioning - `rebar.lock`: Track file, now that rebar3 uses loose dependency versioning - `configure.ac`: When using rebar3, unlock dependencies that are disabled ([#4212](https://github.com/processone/ejabberd/issues/4212?ref=process-one.net)) - `configure.ac`: When using rebar3 with old Erlang, unlock some dependencies ([#4213](https://github.com/processone/ejabberd/issues/4213?ref=process-one.net)) - `mix:exs`: Move `xmpp` from `included_applications` to `applications` ### Dependencies - Base64url: Use only when using rebar2 and Erlang lower than 24 - Idna: Bump from 6.0.0 to 6.1.1 - Jiffy: Use Json module when Erlang/OTP 27, jiffy with older ones - Jose: Update to the new 1.11.10 for Erlang/OTP higher than 23 - Luerl: Update to 1.2.0 when OTP same or higher than 20, simplifies commit a09f222 - P1\_acme: Update to support Jose 1.11.10 and Ipv6 support ([#4170](https://github.com/processone/ejabberd/issues/4170?ref=process-one.net)) - P1\_acme: Update to use Erlang’s json library instead of jiffy when OTP 27 - Port\_compiler: Update to 1.15.0 that supports Erlang/OTP 27.0 ### Development Help - `.gitignore`: Ignore ctags/etags files - `make dialyzer`: Add support to run Dialyzer with Mix - `make format|indent`: New targets to format and indent source code - `make relive`: Add Sync tool with Rebar3, ExSync with Mix - `hook_deps`: Use precise name: hooks are added and later deleted, not removed - `hook_deps`: Fix to handle FileNo as tuple `{FileNumber, CharacterPosition}` - Add support to test also EUnit suite - Fix `code:lib_dir` call to work with Erlang/OTP 27.0-rc2 - Set process flags when Erlang/OTP 27 to help debugging - Test retractions in mam\_tests ### Documentation - Add some XEPs support that was forgotten - Fix documentation links to new URLs generated by MkDocs - Remove `...` in example configuration: it is assumed and reduces verbosity - Support for version note in modules too - Mark toplevel options, commands and modules that changed in latest version - Now modules themselves can have version annotations in `note` ### Installers and Container - make-binaries: Bump Erlang/OTP to 26.2.5 and Elixir 1.16.3 - make-binaries: Bump OpenSSL to 3.3.1 - make-binaries: Bump Linux-PAM to 1.6.1 - make-binaries: Bump Expat to 2.6.2 - make-binaries: Revert temporarily an OTP commit that breaks MSSQL ([#4178](https://github.com/processone/ejabberd/issues/4178?ref=process-one.net)) - CONTAINER.md: Invalid `CTL_ON_CREATE` usage in docker-compose example ### WebAdmin - ejabberd\_ctl: Improve parsing of commas in arguments - ejabberd\_ctl: Fix output of UTF-8-encoded binaries - WebAdmin: Remove webadmin\_view for now, as commands allow more fine-grained permissions - WebAdmin: Unauthorized response: include some text to direct to the logs - WebAdmin: Improve home page - WebAdmin: Sort alphabetically the menu items, except the most used ones - WebAdmin: New login box in the left menu bar - WebAdmin: Add make\_command functions to produce HTML command element - Document ‘any’ argument and result type, useful for internal commands - Commands with ‘internal’ tag: don’t list and block execution by frontends - WebAdmin: Move content to commands; new pages; hook changes; new commands ### Full Changelog [https://github.com/processone/ejabberd/compare/24.02…24.06](https://github.com/processone/ejabberd/compare/24.02...24.06?ref=process-one.net) ## ejabberd 24.06 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you’ve found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Understanding messaging protocols: XMPP and Matrix URL: https://www.process-one.net/blog/xmpp-matrix/ Last updated: 2024-10-10T15:23:54.000Z In the world of real-time communication, two prominent protocols often come into discussion: XMPP and Matrix. Both protocols aim to provide robust and secure messaging solutions, but they differ in architecture, features, and community adoption. This article delves into the key differences and similarities between XMPP and Matrix to help you understand which might be better suited for your needs. ## What is XMPP? ### Overview XMPP (Extensible Messaging and Presence Protocol) is an open-standard communication protocol originally developed for instant messaging (IM). It was designed as the Jabber protocol in 1999 to aggregate communication across a number of options, such as ICQ, Yahoo Messenger, and MSN. It was standardized by the IETF as RFC 3920 and RFC 3921 in 2004, and later revised as RFC 6120 and RFC 6121 in 2011. ### Key Features - **Decentralized Architecture**: XMPP operates on a decentralized network of servers. The protocol is said to be federated. The network of all interconnected XMPP servers is called the XMPP federation. - **Extensibility**: The protocol is highly extensible through XMPP Extension Protocols (XEPs). There are currently more than 400 extensions covering a broad range of use cases like social networking and Internet of Things features through PubSub extensions, Groupchat (aka MUC, Multi-user chat), and VoIP with the Jingle protocol. - **Security**: Supports TLS for encryption and SASL for authentication. End-to-end encryption is available through the OMEMO extension. - **Interoperability**: Widely adopted with numerous clients and servers available. - **Gateways**: Built-in support for gateways to other protocols, allowing for communication across different messaging systems. ### Network Protocol Design - **TCP-Level Stream Protocol**: XMPP is based on a TCP-level stream protocol using XML and namespaces. This extensibility while maintaining schema consistency is key. It can also run on top of other protocols like WebSocket or HTTP through the concept of binding. ### Use Cases - Instant messaging - Presence information - Multi-user chat (MUC) - Social networks - Voice and video calls (with extensions) - Internet of Things - Massive messaging (massive scale messaging platforms like WhatsApp) ## What is Matrix? ### Overview Matrix is an open standard protocol for real-time communication, designed to provide interoperability between different messaging systems. It was introduced in 2014 by the Matrix.org Foundation. ### Key Features - **Decentralized Architecture**: Like XMPP, Matrix is also decentralized and supports a federated model. - **Event-Based Model**: Uses an event-based architecture where all communications are stored in a distributed database. The conversations are replicated on all servers in the federation that participate in the discussion. - **End-to-End Encryption**: Built-in end-to-end encryption using the Olm and Megolm libraries. - **Bridging**: Strong focus on bridging to other communication systems like Slack, IRC, and XMPP. ### Network Protocol Design - **HTTP-Based Protocol**: Matrix uses HTTP for communication and JSON for its data structure, making it suitable for web environments and easy to integrate with web technologies. ### Use Cases - Instant messaging - VoIP and video conferencing - Bridging different chat systems ## Detailled Comparison ### Architecture - **XMPP**: Uses a federated model to build a network of communication that works for both messaging and social networking. The content is not duplicated by default. - **Matrix**: Uses a federated model where each server stores a complete history of conversations, allowing for decentralized control and redundancy. XMPP is built around an event-based architecture to reach the largest possible scale. Matrix is built around a distributed model that may be more appealing to smaller community servers. As the conversations are distributed, it can cope more easily with servers suffering from frequent disconnections in the federated network. ### Extensibility - **XMPP**: Extensible through XEPs that are standardized by the XMPP Standards Foundation, allowing for a wide variety of additional features. As the protocol is based on XML, it can also be extended for custom client features, using your own namespace. The XML schema can be used to define your extension data structure. - **Matrix**: Extensible through modules and APIs, with a strong focus on bridging to other protocols. It is extensible as well and allows custom events and custom properties. ### Security - **XMPP**: Supports TLS for secure communication and SASL for authentication. End-to-end encryption is available through extensions like OMEMO. - **Matrix**: Supports TLS for secure communication. Built-in end-to-end encryption using Olm and Megolm, providing robust security out of the box. Both end-to-end encryption approaches are similar, as they are both based on the same double ratchet encryption algorithm made popular by the Signal messaging platform. ### Interoperability - **XMPP**: Known for its interoperability due to its long-standing presence and wide adoption. Includes built-in support for gateways to other protocols. - **Matrix**: Designed with interoperability in mind, with native support for bridging to other protocols. More recent gateways are available. They could be ported to work on both protocols (which would be neat). ### Scalability - **XMPP**: By design, XMPP has an edge in terms of scalability. XMPP is event-based and works as a broadcast hub for messages, making it efficient in handling a large number of concurrent users. It is proven to sustain millions of concurrent users. - **Matrix**: Matrix maps conversations to documents that are replicated across servers involved in the discussion. This means the document state needs to be merged and reconciled for each new posted message, which incurs significant overhead in terms of processing power, memory, and storage. Its use case is mainly “organization level” chat, supporting thousands of users, not millions. ### Community and Adoption - **XMPP**: Established and widely adopted with a large number of client and server implementations. This can be seen as a drawback, leading to intimidating choices of tools. However, this has proven to be a strength with many competing implementations that have proven to be interoperable. This is a validation of the robustness of the protocol. Initially developed by Jeremy Miller, he cocreated Jabber, Inc to support the first server. The company was later acquired by Cisco. It is now an Internet Engineering Task Force standard used for massive scale deployments and a protocol drive by the non-profit XMPP Standard Foundation. - **Matrix**: Rapidly growing community with increasing adoption, particularly in open-source projects and decentralized applications. The main implementation is developed by Element, the company funded to grow the Matrix protocol. ## Conclusion Both XMPP and Matrix offer robust solutions for real-time communication with their own strengths. XMPP’s long history, extensibility, and efficient scalability make it a reliable choice for traditional instant messaging and presence-based applications, but also social networks, Internet of Things, and workflows that mix human users and devices. On the other hand, Matrix’s architecture, built-in end-to-end encryption, and focus on gateway development make it an excellent choice for those looking to integrate multiple communication systems or require secure corporate messaging through the Element client. Using a server like ejabberd is a future-proof approach, as it is multiprotocol by design. ejabberd supports XMPP, MQTT, SIP, can act as a VoIP and video call proxy (STUN/TURN), and can federate with the Matrix network. It is likely to support the Matrix client protocol as well in beta in the near future. Choosing between XMPP and Matrix depends largely on your specific needs, existing infrastructure, and future scalability requirements. Both protocols continue to evolve, offering exciting possibilities for real-time communication. --- Mistakes? If you spot a mistake, please reach out to share it! Thanks! I would like this document to be as accurate as possible. ### Saying Goodbye to ICQ ! URL: https://www.process-one.net/blog/saying-goodbye-to-icq/ Last updated: 2024-09-16T09:52:00.000Z ICQ was the first messaging software I truly loved and the one that got me into the messaging industry. I still hear its distinctive message notification sound. Back when most users were on dial-up, ICQ’s presence feature was a game changer. Created by Mirabilis in 1996, ICQ was a trailblazer, soon followed by competitors like Yahoo and Microsoft. As an XMPP developer, this moment highlights the value of open standards. Jabber, which evolved into XMPP, was born to centralize all messengers through gateways. Unlike proprietary systems, XMPP offers a decentralized and flexible framework that gives users more control and fosters innovation. This is the end of an era. ICQ lasted 27 years. IRC (Internet Relay Chat), an open protocol, outlived it. So, let’s celebrate and gather in 2026 when XMPP will have lived longer than ICQ. The future is open and federated! ### After Texts.com, Automattic acquires Beeper URL: https://www.process-one.net/blog/after-texts-com-automattic-acquires-beeper/ Last updated: 2024-09-16T09:55:54.000Z Automattic, the company behind WordPress, has taken a significant step in the field of online communication with [the acquisition of Beeper](https://automattic.com/2024/04/09/automattic-acquires-beeper/?ref=process-one.net). This strengthens their messaging position after the acquisition of Texts.com with a similar focus on interop in December 2023\. This move could represent a significant opportunity for the [XMPP](https://xmpp.org/?ref=process-one.net) protocol (eXtensible Messaging and Presence Protocol, formerly known as Jabber), an open standard for instant messaging. XMPP, known for its role in unifying messaging services like ICQ, MSN, and Yahoo in the early 2000s, remains a pillar of interoperability. With this acquisition, Automattic could potentially align Beeper with XMPP to promote a more open and interconnected messaging ecosystem. While Beeper was already integrating messages from various platforms into a single application, adopting XMPP as a pivot format could further facilitate these connections, leveraging a protocol already standardized by the IETF. This acquisition, announced in early April, comes just after the implementation in Europe of the Digital Markets Act, which requires major instant messaging operators to open their messaging systems to allow for interoperability. Automattic’s central position in web hosting and its approach based on standards and open source code could enable a significant player to influence discussions between Europe and major proprietary messaging players. If you add the fact that Apple will add support for RCS (Rich Communication Suite) in iMessage to enable better interoperability with Android devices, something is really changing in the messaging world. **Is this a new hope for the future of messaging?** ### ejabberd Docs now using MkDocs URL: https://www.process-one.net/blog/ejabberd-docs-now-using-mkdocs/ Last updated: 2024-09-16T09:58:40.000Z ## Brief documentation timeline ejabberd started in November 2002 (see a timeline in the [ejabberd turns 20](https://www.process-one.net/blog/ejabberd-turns-20/) blog post). And the first documentation was published in January 2003, using LaTeX, see [Ejabberd Installation and Operation Guide](https://web.archive.org/web/20030409163941/http://ejabberd.jabberstudio.org/guide.html). That was one single file, hosted in the ejabberd CVS source code repository, and was available as a single HTML file and a PDF. As the project grew and got more content, in 2015 the documentation was [converted from LaTeX to Markdown](https://www.process-one.net/blog/ejabberd-new-documentation-site-a-community-effort/), moved from ejabberd repository to a dedicated [docs.ejabberd.im](https://github.com/processone/docs.ejabberd.im?ref=process-one.net) git repository, and published using a Go HTTP server in `docs.ejabberd.im`, see an [archived ejabberd Docs site](https://web.archive.org/web/20240327173114/https://docs.ejabberd.im/). ## New ejabberd Docs site Now the ejabberd documentation has moved to MkDocs+Material, and this brings several changes and improvements: #### Site and Web Server: - Replaced Go site with [MkDocs](https://www.mkdocs.org/?ref=process-one.net) - [Material](https://squidfunk.github.io/mkdocs-material/?ref=process-one.net) theme for great features and visual appeal, including light/dark color schemes - Still written in Markdown, but now using several MkDocs, Material and [Python-Markdown](https://python-markdown.github.io/extensions/?ref=process-one.net) extensions - The online site is built by GitHub Actions and hosted in Pages, with smaller automatic deployment time - Offline reading: the `ejabberd Docs` site can be downloaded as a PDF or zipped HTML, see the links in [home page](https://docs.ejabberd.im/?ref=process-one.net) #### Navigation - Major navigation reorganization, keeping URLs intact so old links still work (only Install got some relevant URL changes) - [Install](https://docs.ejabberd.im/admin/install/?ref=process-one.net) section is split into several sections: Containers, Binaries, Compile, … - Reorganized the [Archive](https://docs.ejabberd.im/archive/?ref=process-one.net) section, and now it includes the corresponding Upgrade notes - Several markdown files from the ejabberd and docker-ejabberd repositories are now incorporated here #### Content - Many markdown visual improvements, specially in code snippets - Options and commands that were modified in the last release will show a mark, see for example [API Reference](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net) - Version annotations are shown after the corresponding title, see for example [sql\_flags](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#sql%5Fflags) - Modules can have version annotations, see for example [mod\_matrix\_gw](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod%5Fmatrix%5Fgw) - Links to modules, options and API now use the real name with `_` character instead of `-` (compare old [#auth-opts](https://web.archive.org/web/20231220132058/https://docs.ejabberd.im/admin/configuration/toplevel/#auth-opts) with [#auth\_opts](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#auth%5Fopts)). The old links are still supported, no broken links. - [Listen Modules](https://docs.ejabberd.im/admin/configuration/listen/?ref=process-one.net) section is now better organized - New experimental [ejabberd Developer Livebook](https://docs.ejabberd.im/livebooks/ejabberd-developer-livebook/?ref=process-one.net) So, please check the revamped [ejabberd Docs](https://docs.ejabberd.im/?ref=process-one.net) site, and head to [docs.ejabberd.im git repository](https://github.com/processone/docs.ejabberd.im?ref=process-one.net) to report problems and propose improvements. ### Matrix gateway setup with ejabberd URL: https://www.process-one.net/blog/matrix-gateway-setup-with-ejabberd/ Last updated: 2025-06-05T20:45:47.000Z ## Configuration in ejabberd ### HTTPS listener First, add an [HTTP handler](https://docs.ejabberd.im/admin/configuration/listen/?ref=process-one.net#ejabberd-http), as Matrix uses HTTPS for Server-Server API. In the [listen section](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#listen) of your `ejabberd.yml` configuration file, add a handler on Matrix port `8448` for path `/_matrix` that calls the `mod_matrix_gw` module. You must enable TLS on this port to accept HTTPS connections (unless a proxy already handles HTTPS in front of ejabberd) and provide a valid certificate for your Matrix domain (see `matrix_domain` below). You can set this certificate using the [certfile option](https://docs.ejabberd.im/admin/configuration/listen-options/?ref=process-one.net#certfile) of the listener, like in the example below, or listing it in the [certfiles top level option](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#certfiles). *Example*: ```yaml listen: - port: 5222 module: ejabberd_c2s - port: 8448 # Matrix federation module: ejabberd_http tls: true certfile: "/opt/ejabberd/conf/matrix.pem" request_handlers: "/_matrix": mod_matrix_gw ``` If you want to use a non-standard port instead of `8448`, you must serve a `/.well-known/matrix/server` on your Matrix domain (see below). ### Server-to-Server You must enable s2s (Server-to-Server federation) by setting an [access rule](https://docs.ejabberd.im/admin/configuration/basic/?ref=process-one.net#access-rules) `all` or `allow` on [s2s\_access](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#s2s-access) top level option: *Example*: ```yaml s2s_access: s2s access_rules: local: - allow: local c2s: - deny: blocked - allow s2s: - allow # to allow Matrix federation ``` ### Matrix gateway module Finally, add [mod\_matrix\_gw](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod-matrix%5Fgw) module in the [modules](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#modules) list. *Example*: ```yaml modules: mod_matrix_gw: matrix_domain: "matrixdomain.com" key_name: "key1" key: "SU4mu/j8b8A1i1EdyxIcKlFlrp+eSRBIlZwGyHP7Mfo=" ``` #### `matrix_domain` Replace `matrixdomain.com` with your Matrix domain. That domain must resolve to your ejabberd server or [serve a file](https://www.process-one.net/blog/matrix-gateway-setup-with-ejabberd/%60https://matrix-org.github.io/matrix-authentication-service/setup/well-known.html%60) https://matrixdomain.com/.well-known/matrix/server that contains a JSON file with the address and Matrix port (as defined by the Matrix HTTPS handler, see above) of your ejabberd server: **Example:** ```json { "m.server": "ejabberddomain.com:8448" } ``` #### `key_name` & `key` The `key_name` is arbitrary. The `key` value is your base64-encoded ed25519 [Matrix signing key](https://matrix-org.github.io/dendrite/installation/manual/signingkeys?ref=process-one.net). It can be generated by Matrix tools or in an Erlang shell using the command `base64:encode(element(2, crypto:generate_key(eddsa, ed25519))).`: **Example:** ```shell $ erl Erlang/OTP 24 [erts-12.3.1] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [dtrace] Eshell V12.3.1 (abort with ^G) 1> base64:encode(element(2, crypto:generate_key(eddsa, ed25519))). <<"SU4mu/j8b8A1i1EdyxIcKlFlrp+eSRBIlZwGyHP7Mfo=">> 2> q(). ok ``` Once your configuration is ready, you can restart ejabberd. ## Testing To check if your setup is correct, go to the following page and enter your Matrix domain (as set by the `matrix_domain` option): [https://federationtester.matrix.org/](https://federationtester.matrix.org/?ref=process-one.net) This page should list any problem related to Matrix on your ejabberd installation. ## Routing What messages are routed to an external Matrix server? ### Implicit routing Let’s say an XMPP client connected to your ejabberd server sends a message to a JID `user1@domain1.com`. If `domain1.com` is defined by the [hosts](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#hosts) parameter of your ejabberd server (i.e. it’s one of your XMPP domains), the message will be routed locally. If it’s not, ejabberd will try to establish an XMPP Server-to-Server connection to a remote `domain1.com` XMPP server. If this fails (i.e. there is no such external XMPP domain), then ejabberd will try to route the message over the Matrix federation by transforming the JID `user1@domain1.com` into the Matrix ID `@user1:domain1.com` and attempt to open a connection to the remote Matrix domain. This behavior is enabled when the `matrix_id_as_jid` option in the `mod_matrix_gw` module is set to `true`. ### Explicit routing It is also possible to route messages explicitly to the Matrix federation by setting the option `matrix_id_as_jid` in the `mod_matrix_gw` module to **`false`**: Example: ``` modules: mod_matrix_gw: host: "matrix.@HOST@" matrix_domain: "matrixdomain.com" key_name: "key1" key: "SU4mu/j8b8A1i1EdyxIcKlFlrp+eSRBIlZwGyHP7Mfo=" matrix_id_as_jid: false ``` In this case, the automatic fallback from XMPP to Matrix when XMPP Server-to-Server fails is **enabled**: if ejabberd cannot deliver a message to an XMPP domain, it will try to route it via Matrix by transforming the JID (e.g. `user@matrixdomain.tld`) into a Matrix ID (e.g. `@user:matrixdomain.tld`). To send a message to the Matrix user `@user:remotedomain.com`, the XMPP client must send a message to the JID `user%remotedomain.com@matrix.xmppdomain.com`, where `matrix.xmppdomain.com` is the JID of the gateway service as set by the `host` option of the `mod_matrix_gw` module (the keyword `@HOST@` is replaced with the XMPP domain of the server). If `host` is not set, the Matrix gateway JID is your XMPP domain with the `matrix.` prefix added. --- #### 🛠️ Update n°2 (2025/06/05 22:44) Thanks to the feedback from the community, this post has been updated to reflect the [correct behavior](https://github.com/processone/docs.ejabberd.im/commit/57ae13bf40ed?ref=process-one.net) of the `matrix_id_as_jid` option in `mod_matrix_gw`. - `matrix_id_as_jid: true` → enables implicit fallback to Matrix when XMPP s2s fails. - `matrix_id_as_jid: false` (default) → disables fallback; messages must be explicitly routed to the Matrix gateway. ### ejabberd 24.02 URL: https://www.process-one.net/blog/ejabberd-24-02/ Last updated: 2024-09-16T10:06:14.000Z ejabberd 24.02 has just been release and well, this is a huge release with 200 commits and more in the libraries. We’ve packed this update with a plethora of new features, significant improvements, and essential bug fixes, all designed to supercharge your messaging infrastructure. - [**Matrix**](https://matrix.org/?ref=process-one.net) **Federation Unleashed:** Imagine seamlessly connecting with Matrix servers – it’s now possible! ejabberd breaks new ground in cross-platform communication, fostering a more interconnected messaging universe. We have still some ground to cover and for that we are waiting for your feedback. - **Cutting-Edge Security with** [**TLS 1.3 & SASL2**](https://www.process-one.net/blog/ejabberd-24-02/#tls)**:** In an era where security is paramount, ejabberd steps up its game. With support for TLS 1.3 and advanced SASL2 protocols, we increase the overall security for all platform users. - **Performance Enhancements with Bind 2:** Faster connection times, especially crucial for mobile network users, thanks to Bind 2 and other performance optimizations. - **User gains better control over on their messages:** The new support for [XEP-0424](https://www.process-one.net/blog/ejabberd-24-02/#424): Message Retraction allows users to manage their message history and remove something they posted by mistake. - **Optimized server pings** by relying on an existing mechanism coming from [XEP-0198](https://www.process-one.net/blog/ejabberd-24-02/#198) - **Streamlined API Versioning:** Our refined [API versioning](https://www.process-one.net/blog/ejabberd-24-02/#api) means smoother, more flexible integration for your applications. - **Enhanced** [**Elixir, Mix and Rebar3**](https://www.process-one.net/blog/ejabberd-24-02/#compilation) **Support** If you upgrade ejabberd from a previous release, please review those changes: - [Update the SQL schema](https://www.process-one.net/blog/ejabberd-24-02/#sql) - Update API commands as explained below, or use [API versioning](https://www.process-one.net/blog/ejabberd-24-02/#api) - [Mix or Rebar3 used by default instead of Rebar to compile ejabberd](https://www.process-one.net/blog/ejabberd-24-02/#mixdefault) - [Authentication workaround for Converse.js and Strophe.js](https://www.process-one.net/blog/ejabberd-24-02/#converse) A more detailed explanation of those topics and other features: ## Matrix federation ejabberd is now able to [federate](https://matrix-org.github.io/synapse/latest/federate.html?ref=process-one.net) with [Matrix](https://matrix.org/?ref=process-one.net) servers. Detailed instructions to setup Matrix federation with ejabberd will be detailed in another post. Here is a quick summary of the configuration steps: First, [s2s](https://datatracker.ietf.org/doc/html/rfc3920?ref=process-one.net#section-2.5) must be enabled on ejabberd. Then define a listener that uses `mod_matrix_gw`: ```yaml listen: - port: 8448 module: ejabberd_http tls: true certfile: "/opt/ejabberd/conf/server.pem" request_handlers: "/_matrix": mod_matrix_gw ``` And add `mod_matrix_gw` in your modules: ```yaml modules: mod_matrix_gw: matrix_domain: "domain.com" key_name: "somename" key: "yourkeyinbase64" ``` ## Support TLS 1.3, Bind 2, SASL2 - [RFC 9266 Channel Bindings for TLS 1.3](https://www.rfc-editor.org/rfc/rfc9266?ref=process-one.net): This enhances security and reliability. - [XEP-0386: Bind 2](https://xmpp.org/extensions/xep-0386.html?ref=process-one.net): This is going to reduce the connection time for clients. This is especially important if you are using XMPP to connect from a mobile network. - [XEP-0388: Extensible SASL Profile – SASL2](https://xmpp.org/extensions/xep-0388.html?ref=process-one.net) - [XEP-0440: SASL Channel-Binding Type Capability](https://xmpp.org/extensions/xep-0440.html?ref=process-one.net): These updates are aimed at bolstering our authentication mechanisms. - [XEP-0474: SASL SCRAM Downgrade Protection](https://xmpp.org/extensions/xep-0474.html?ref=process-one.net) ## Support for XEP-0424 Message Retraction With the new support for [XEP-0424: Message Retraction](https://xmpp.org/extensions/xep-0424.html?ref=process-one.net), users of MAM message archiving can control their message archiving, with the ability to ask for deletion. ## Support for XEP-0198 pings If stream management is enabled, let mod\_ping trigger [XEP-0198](https://xmpp.org/extensions/xep-0198.html?ref=process-one.net) `equests` rather than sending [XEP-0199](https://xmpp.org/extensions/xep-0199.html?ref=process-one.net) pings. This avoids the overhead of the ping IQ stanzas, which, if stream management is enabled, are accompanied by XEP-0198 elements anyway. ## Update the SQL schema The table `archive` has a text column named `origin_id` (see [commit 975681](https://github.com/processone/ejabberd/commit/975681?ref=process-one.net)). You have two methods to update the SQL schema of your existing database: If using MySQL or PosgreSQL, you can enable the option [update\_sql\_schema](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#update-sql-schema) and ejabberd will take care to update the SQL schema when needed: add in your ejabberd configuration file the line `update_sql_schema: true` If you are using other database, or prefer to update manually the SQL schema: - MySQL default schema: ```sql ALTER TABLE archive ADD COLUMN origin_id varchar(191) NOT NULL DEFAULT ''; ALTER TABLE archive ALTER COLUMN origin_id DROP DEFAULT; CREATE INDEX i_archive_username_origin_id USING BTREE ON archive(username(191), origin_id(191)); ``` - MySQL new schema: ```sql ALTER TABLE archive ADD COLUMN origin_id varchar(191) NOT NULL DEFAULT ''; ALTER TABLE archive ALTER COLUMN origin_id DROP DEFAULT; CREATE INDEX i_archive_sh_username_origin_id USING BTREE ON archive(server_host(191), username(191), origin_id(191)); ``` - PostgreSQL default schema: ```sql ALTER TABLE archive ADD COLUMN origin_id text NOT NULL DEFAULT ''; ALTER TABLE archive ALTER COLUMN origin_id DROP DEFAULT; CREATE INDEX i_archive_username_origin_id ON archive USING btree (username, origin_id); ``` - PostgreSQL new schema: ```sql ALTER TABLE archive ADD COLUMN origin_id text NOT NULL DEFAULT ''; ALTER TABLE archive ALTER COLUMN origin_id DROP DEFAULT; CREATE INDEX i_archive_sh_username_origin_id ON archive USING btree (server_host, username, origin_id); ``` - MSSQL default schema: ```sql ALTER TABLE [dbo].[archive] ADD [origin_id] VARCHAR (250) NOT NULL; CREATE INDEX [archive_username_origin_id] ON [archive] (username, origin_id) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); ``` - MSSQL new schema: ```sql ALTER TABLE [dbo].[archive] ADD [origin_id] VARCHAR (250) NOT NULL; CREATE INDEX [archive_sh_username_origin_id] ON [archive] (server_host, username, origin_id) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); ``` - SQLite default schema: ```sql ALTER TABLE archive ADD COLUMN origin_id text NOT NULL DEFAULT ''; CREATE INDEX i_archive_username_origin_id ON archive (username, origin_id); ``` - SQLite new schema: ```sql ALTER TABLE archive ADD COLUMN origin_id text NOT NULL DEFAULT ''; CREATE INDEX i_archive_sh_username_origin_id ON archive (server_host, username, origin_id); ``` ## Authentication workaround for Converse.js and Strophe.js This ejabberd release includes support for [XEP-0474: SASL SCRAM Downgrade Protection](https://xmpp.org/extensions/xep-0474.html?ref=process-one.net), and some clients may not support it correctly yet. If you are using [Converse.js](https://github.com/conversejs/converse.js?ref=process-one.net) 10.1.6 or older, [Movim](https://github.com/movim/movim?ref=process-one.net) 0.23 Kojima or older, or any other client based in [Strophe.js](https://github.com/strophe/strophejs?ref=process-one.net) v1.6.2 or older, you may notice that they cannot authenticate correctly to ejabberd. To solve that problem, either update to newer versions of those programs (if they exist), or you can enable temporarily the option [disable\_sasl\_scram\_downgrade\_protection](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#disable-sasl-scram-downgrade-protection) in the ejabberd configuration file `ejabberd.yml` like this: ```yaml disable_sasl_scram_downgrade_protection: true ``` ## Support for API versioning Until now, when a new ejabberd release changed some API command (an argument renamed, a result in a different format…), then you had to update your API client to the new API at the same time that you updated ejabberd. Now the ejabberd API commands can have different versions, by default the most recent one is used, and the API client can specify the API version it supports. In fact, this feature was [implemented seven years ago](https://github.com/processone/ejabberd/commit/3dc55c6d47e3093a6147ce275c7269a7d08ffc45?ref=process-one.net), included in [ejabberd 16.04](https://www.process-one.net/blog/ejabberd-16-04/), documented in [ejabberd Docs: API Versioning](https://docs.ejabberd.im/developer/ejabberd-api/api%5Fversioning/?ref=process-one.net)… but it was never actually used! This ejabberd release includes many fixes to get API versioning up to date, and it starts being used by several commands. Let’s say that ejabberd 23.10 implemented API version 0, and this ejabberd 24.02 adds API version 1\. You may want to update your API client to use the new API version 1… or you can continue using API version 0 and delay API update a few weeks or months. To continue using API version 0: – if using ejabberdctl, use the switch `--version 0`. For example: `ejabberdctl --version 0 get_roster admin localhost` – if using mod\_http\_api, in ejabberd configuration file add `v0` to the `request_handlers` path. For example: `/api/v0: mod_http_api` Check the details in [ejabberd Docs: API Versioning](https://docs.ejabberd.im/developer/ejabberd-api/api%5Fversioning/?ref=process-one.net). ## ejabberd commands API version 1 When you want to update your API client to support ejabberd API version 1, those are the changes to take into account: – Commands with list arguments – mod\_http\_api does not name integer and string results – ejabberdctl with list arguments – ejabberdctl list results All those changes are described in the next sections. ## Commands with list arguments Several commands now use `list` argument instead of a `string` with separators (different commands used different separators: `;` `:` `\\n` `,`). The commands improved in API version 1: – [add\_rosteritem](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#add-rosteritem) – [oauth\_issue\_token](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#oauth-issue-token) – [send\_direct\_invitation](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#send-direct-invitation) – [srg\_create](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#srg-create) – [subscribe\_room](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#subscribe-room) – [subscribe\_room\_many](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#subscribe-room-many) For example, `srg_create` in API version 0 took as arguments: ```erlang {"group": "group3", "host": "myserver.com", "label": "Group3", "description": "Third group", "display": "group1\\ngroup2"} ``` now in API version 1 the command expects as arguments: ```erlang {"group": "group3", "host": "myserver.com", "label": "Group3", "description": "Third group", "display": ["group1", "group2"]} ``` ## mod\_http\_api not named results There was an incoherence in mod\_http\_api results when they were integer/string and when they were list/tuple/rescode…: the result contained the name, for example: ```bash $ curl -k -X POST -H "Content-type: application/json" -d '{}' "http://localhost:5280/api/get_loglevel/v0" {"levelatom":"info"} ``` Staring in API version 1, when result is an integer or a string, it will not contain the result name. This is now coherent with the other result formats (list, tuple, …) which don’t contain the result name either. Some examples with API version 0 and API version 1: ```bash $ curl -k -X POST -H "Content-type: application/json" -d '{}' "http://localhost:5280/api/get_loglevel/v0" {"levelatom":"info"} $ curl -k -X POST -H "Content-type: application/json" -d '{}' "http://localhost:5280/api/get_loglevel" "info" $ curl -k -X POST -H "Content-type: application/json" -d '{"name": "registeredusers"}' "http://localhost:5280/api/stats/v0" {"stat":2} $ curl -k -X POST -H "Content-type: application/json" -d '{"name": "registeredusers"}' "http://localhost:5280/api/stats" 2 $ curl -k -X POST -H "Content-type: application/json" -d '{"host": "localhost"}' "http://localhost:5280/api/registered_users/v0" ["admin","user1"] $ curl -k -X POST -H "Content-type: application/json" -d '{"host": "localhost"}' "http://localhost:5280/api/registered_users" ["admin","user1"] ``` ## ejabberdctl with list arguments ejabberdctl now supports list and tuple arguments, like mod\_http\_api and ejabberd\_xmlrpc. This allows ejabberdctl to execute all the existing commands, even some that were impossible until now like `create_room_with_opts` and `set_vcard2_multi`. List elements are separated with `,` and tuple elements are separated with `:`. Relevant commands: – [add\_rosteritem](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#add-rosteritem) – [create\_room\_with\_opts](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#create-room-with-opts) – [oauth\_issue\_token](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#oauth-issue-token) – [send\_direct\_invitation](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#send-direct-invitation) – [set\_vcard2\_multi](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#set-vcard2-multi) – [srg\_create](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#srg-create) – [subscribe\_room](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#subscribe-room) – [subscribe\_room\_many](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#subscribe-room-many) Some example uses: ```bash ejabberdctl add_rosteritem user1 localhost testuser7 localhost NickUser77l gr1,gr2,gr3 both ejabberdctl create_room_with_opts room1 conference.localhost localhost public:false,persistent:true ejabberdctl subscribe_room_many user1@localhost:User1,admin@localhost:Admin room1@conference.localhost urn:xmpp:mucsub:nodes:messages,u ``` ## ejabberdctl list results Until now, ejabberdctl returned list elements separated with `;`. Now in API version 1 list elements are separated with `,`. For example, in ejabberd 23.10: ```bash $ ejabberdctl get_roster admin localhost jan@localhost jan none subscribe group1;group2 tom@localhost tom none subscribe group3 ``` Since this ejabberd release, using API version 1: ```bash $ ejabberdctl get_roster admin localhost jan@localhost jan none subscribe group1,group2 tom@localhost tom none subscribe group3 ``` it is still possible to get the results in the old syntax, using API version 0: ```bash $ ejabberdctl --version 0 get_roster admin localhost jan@localhost jan none subscribe group1;group2 tom@localhost tom none subscribe group3 ``` ## ejabberdctl help improved ejabberd supports around 200 administrative commands, and probably you consult them in the ejabberd Docs -> [API Reference](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net) page, where all the commands documentation is perfectly displayed… The `ejabberdctl` command-line script already allowed to consult the commands documentation, consulting in real-time your ejabberd server to show you exactly the commands that are available. But it lacked some details about the commands. That has been improved, and now `ejabberdctl` shows all the information, including arguments description, examples and version notes. For example, the `connected_users_vhost` command documentation as seen in the [ejabberd Docs site](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#connected-users-vhost) is equivalently visible using `ejabberdctl`: ```bash $ ejabberdctl help connected_users_vhost Command Name: connected_users_vhost Arguments: host::binary : Server name Result: connected_users_vhost::[ sessions::string ] Example: ejabberdctl connected_users_vhost "myexample.com" user1@myserver.com/tka user2@localhost/tka Tags: session Module: mod_admin_extra Description: Get the list of established sessions in a vhost ``` ## Experimental support for Erlang/OTP 27 Erlang/OTP 27.0-rc1 was recently released, and ejabberd can be compiled with it. If you are developing or experimenting with ejabberd, it would be great if you can use Erlang/OTP 27 and report any problems you find. For production servers, it’s recommended to stick with Erlang/OTP 26.2 or any previous version. In this sense, the `rebar` and `rebar3` binaries included with ejabberd are also updated: now they support from Erlang 24 to Erlang 27\. If you want to use older Erlang versions from 20 to 23, there are compatible binaries available in git: [rebar from ejabberd 21.12](https://github.com/processone/ejabberd/raw/21.12/rebar?ref=process-one.net) and [rebar3 from ejabberd 21.12](https://github.com/processone/ejabberd/raw/21.12/rebar3?ref=process-one.net). Of course, if you have `rebar` or `rebar3` already installed in your system, it’s preferable if you use those ones, because probably they will be perfectly compatible with whatever erlang version you have installed. ## Installers and `ejabberd` container image The binary installers now include the recent and stable Erlang/OTP 26.2.2 and Elixir 1.16.1\. Many other dependencies were updated in the installers, the most notable is OpenSSL that has jumped to version 3.2.1. The [ejabberd container image](https://github.com/processone/ejabberd/blob/master/CONTAINER.md?ref=process-one.net) and the [ecs container image](https://github.com/processone/docker-ejabberd/blob/master/ecs/README.md?ref=process-one.net) have gotten all those version updates, and also Alpine is updated to 3.19. By the way, this container image already had support to [run commands when the container starts](https://github.com/processone/ejabberd/blob/master/CONTAINER.md?ref=process-one.net#commands-on-start)… And now you can setup the commands to allow them fail, by prepending the character `!`. ## Summary of compilation methods When compiling ejabberd from source code, you may have noticed there are a lot of possibilities. Let’s take an overview before digging in the new improvements: - Tools to manage the dependencies and compilation: - [Rebar](https://github.com/rebar/rebar?ref=process-one.net): it is nowadays very obsolete, but still does the job of compiling ejabberd - [Rebar3](https://github.com/erlang/rebar3?ref=process-one.net): the successor of Rebar, with many improvements and plugins, supports [hex.pm](https://hex.pm/?ref=process-one.net) and Elixir compilation - [Mix](https://hexdocs.pm/mix/1.16.0/Mix.html?ref=process-one.net): included with the [Elixir programming language](https://elixir-lang.org/?ref=process-one.net), supports hex.pm, and erlang compilation - Installation methods: - `make install`: copies the files to the system - `make prod`: prepares a self-contained [OTP production release](https://www.erlang.org/doc/design%5Fprinciples/release%5Fstructure?ref=process-one.net) in `_build/prod/`, and generates a `tar.gz` file. This was previously named `make rel` - `make dev`: prepares quickly an OTP development release in `_build/dev/` - `make relive`: prepares the barely minimum in `_build/relive/` to run ejabberd and starts it - Start scripts and alternatives: - `ejabberdctl` with erlang shell: `start`/`foreground`/`live` - `ejabberdctl` with elixir shell: `iexlive` - `ejabberd` `console`/`start` (this script is generated by rebar3 or mix, and does not support ejabberdctl configurable options) For example: – the [CI](https://github.com/processone/ejabberd/actions/workflows/ci.yml?ref=process-one.net) dynamic tests use `rebar3`, and [Runtime](https://github.com/processone/ejabberd/actions/workflows/runtime.yml?ref=process-one.net) tries to test all the possible combinations – ejabberd [binary installers](https://github.com/processone/ejabberd/actions/workflows/installers.yml?ref=process-one.net) are built using: `mix + make prod` – [container images](https://github.com/processone/ejabberd/actions/workflows/container.yml?ref=process-one.net) are built using: `mix + make prod` too, and started with `ejabberdctl foreground` Several combinations didn’t work correctly until now and have been fixed, for example: – `mix + make relive` – `mix + make prod/dev + ejabberdctl iexlive` – `mix + make install + ejabberdctl start/foregorund/live` – `make uninstall` buggy has an experimental alternative: `make uninstall-rel` – `rebar + make prod` with Erlang 26 ## Use Mix or Rebar3 by default instead of Rebar to compile ejabberd ejabberd uses [Rebar](https://github.com/rebar/rebar?ref=process-one.net) to manage dependencies and compilation since ejabberd [13.10](https://www.process-one.net/blog/ejabberd-community-13-10/) [4d8f770](https://github.com/processone/ejabberd/commit/4d8f7706240a1603468968f47fc7b150b788d62f?ref=process-one.net). However, that tool is obsolete and unmaintained since years ago, because there is a complete replacement: [Rebar3](https://github.com/erlang/rebar3?ref=process-one.net) is supported by ejabberd since [20.12](https://www.process-one.net/blog/ejabberd-20-12/) [0fc1aea](https://github.com/processone/ejabberd/commit/0fc1aea379924b6f83f274f173d0bbd163cae1c2?ref=process-one.net). Among other benefits, this allows to download dependencies from [hex.pm](https://hex.pm/?ref=process-one.net) and cache them in your system instead of downloading them from git every time, and allows to compile Elixir files and Elixir dependencies. In fact, ejabberd can be compiled using `mix` (a tool included with the [Elixir programming language](https://elixir-lang.org/?ref=process-one.net)) since ejabberd [15.04](https://www.process-one.net/blog/ejabberd-15-04/) [ea8db99](https://github.com/processone/ejabberd/commit/ea8db9967fbfe53f581c3ae721657d9e6f919864?ref=process-one.net) (with improvements in ejabberd [21.07](https://www.process-one.net/blog/ejabberd-22-07/) [4c5641a](https://github.com/processone/ejabberd/commit/4c5641a6489d0669b4220b5ac759a4e1271af3b5?ref=process-one.net)) For those reasons, the tool selection performed by `./configure` will now be: – If `--with-rebar=rebar3` but Rebar3 not found installed in the system, use the `rebar3` binary included with ejabberd – Use the program specified in option: `--with-rebar=/path/to/bin` – If none is specified, use the system `mix` – If Elixir not found, use the system `rebar3` – If Rebar3 not found, use the `rebar3` binary included with ejabberd ## Removed Elixir support in Rebar Support for Elixir 1.1 was added as a dependency in commit [01e1f67](https://github.com/processone/ejabberd/commit/01e1f677c72b923251f7021bc024319ff129d42d?ref=process-one.net) to ejabberd [15.02](https://www.process-one.net/blog/ejabberd-community-15-02/). This allowed to compile Elixir files. But since Elixir 1.4.5 (released Jun 22, 2017) it isn’t possible to get Elixir as a dependency… it’s nowadays a standalone program. For that reason, support to download old Elixir 1.4.4 as a dependency has been removed. When Elixir support is required, better simply install Elixir and use `mix` as build tool: ```bash ./configure --with-rebar=mix ``` Or install Elixir and use the experimental Rebar3 support to compile Elixir files and dependencies: ```bash ./configure --with-rebar=rebar3 --enable-elixir ``` ## Added Elixir support in Rebar3 It is now possible to compile ejabberd using Rebar3 and support Elixir compilation. This compiles the Elixir files included in ejabberd’s `lib/` path. There’s also support to get dependencies written in Elixir, and it’s possible to build OTP releases including Elixir support. It is necessary to have Elixir installed in the system, and configure the compilation using `--enable-elixir`. For example: ```bash apt-get install erlang erlang-dev elixir git clone https://github.com/processone/ejabberd.git ejabberd cd ejabberd ./autogen.sh ./configure --with-rebar=rebar3 --enable-elixir make make dev _build/dev/rel/ejabberd/bin/ejabberdctl iexlive ``` ## Elixir versions supported [Elixir](https://elixir-lang.org/?ref=process-one.net) 1.10.3 is the minimum supported, but: – Elixir 1.10.3 or higher is required to build an OTP release with `make prod` or `make dev` – Elixir 1.11.4 or higher is required to build an OTP release if using Erlang/OTP 24 or higher – Elixir 1.11.0 or higher is required to use `make relive` – Elixir 1.13.4 with Erlang/OTP 23.0 are the lowest versions tested by [Runtime](https://github.com/processone/ejabberd/actions/workflows/runtime.yml?ref=process-one.net) For all those reasons, if you want to use Elixir, it is highly recommended to use Elixir 1.13.4 or higher with Erlang/OTP 23.0 or higher. ## `make rel` is renamed to `make prod` When ejabberd started to use Rebar2 build tool, that tool could create an OTP release, and the target in `Makefile.in` was conveniently named `make rel`. However, newer tools like Rebar3 and Elixir’s Mix support creating different types of releases: production, development, … In this sense, our `make rel` target is nowadays more properly named `make prod`. For backwards compatibility, `make rel` redirects to `make prod`. ## New `make install-rel` and `make uninstall-rel` This is an alternative method to install ejabberd in the system, based in the OTP release process. It should produce exactly the same results than the existing `make install`. The benefits of `make install-rel` over the existing method: – this uses OTP release code from rebar/rebar3/mix, and consequently requires less code in our `Makefile.in` – `make uninstall-rel` correctly deletes all the library files This is still experimental, and it would be great if you are able to test it and report any problem; eventually this method could replace the existing one. Just for curiosity: – ejabberd 13.03-beta1 got support for `make uninstall` [was added](https://github.com/processone/ejabberd/commit/bfb7583bb287e3e4ccabdf8b7e109702366b2971?ref=process-one.net) – [ejabberd 13.10](https://www.process-one.net/blog/ejabberd-community-13-10/) introduced [Rebar build tool](https://github.com/processone/ejabberd/commit/4d8f7706240a1603468968f47fc7b150b788d62f?ref=process-one.net) and code got more modular – ejabberd 15.10 started to [use the OTP directory structure for ‘make install’](https://github.com/processone/ejabberd/commit/70606667c60bfc3196defe86056a5eb77841dfd5?ref=process-one.net), and this [broke make uninstall](https://github.com/processone/ejabberd/issues/1496?ref=process-one.net) ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Holger Weiß](https://github.com/weiss?ref=process-one.net) for the support XEP-0198 pings and XEP-0425 fixes - [Mr. EddX](https://github.com/MrEddX?ref=process-one.net), updated the Bulgarian translation - [Sketch6580](https://hosted.weblate.org/user/Sketch6580/?ref=process-one.net), updated the Chinese translation - [Jan Aschenbrenner](https://hosted.weblate.org/user/JanAschenbrenner/?ref=process-one.net), updated the Czech translation - [Ranforingus](https://hosted.weblate.org/user/ranforingus/?ref=process-one.net), updated the Dutch translation - [Ermete Melchiorre](https://github.com/sudcapitano?ref=process-one.net), updated the Italian translation - [Mako N](https://github.com/mako09?ref=process-one.net), updated the Japanese translation - [Silvério Santos](https://github.com/SantosSi?ref=process-one.net), updated the Portuguese translation - [Олександр Кревський](https://github.com/KPEBA?ref=process-one.net), updated the Ukrainian translation And also to all the people contributing in the ejabberd chatroom, issue tracker… ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/), in addition to all those improvements and bugfixes, also get: ### Push - Fix clock issue when signing Apple push JWT tokens - Share Apple push JWT tokens between nodes in cluster - Increase allowed certificates chain depth in GCM requests - Use `x:oob` data as source for image delivered in pushes - Process only https urls in oob as images in pushes - Fix jid in disable push iq generated by GCM and Webhook service - Add better logging for `TooManyProviderTokenUpdated` error - Make `get_push_logs` command generate better error if `mod_push_logger` not available - Add command `get_push_logs` that can be used to retrieve info about recent pushes and errors reported by push services - Add support for webpush protocol for sending pushes to safari/chrome/firefox browsers ### MAM - Expand `mod_mam_http_access` API to also accept range of messages ### MUC - Update `mod_muc_state_query` to fix `subject_author` room state field - Fix encoding of config `xdata` in `mod_muc_state_query` ### PubSub - Allow pubsub node owner to overwrite items published by other persons (p1db) ## ChangeLog This is a more detailed list of changes in this ejabberd release: ### Core - Added Matrix gateway in `mod_matrix_gw` - Support SASL2 and Bind2 - Support tls-server-end-point channel binding and sasl2 codec - Support tls-exporter channel binding - Support XEP-0474: SASL SCRAM Downgrade Protection - Fix presenting features and returning results of inline bind2 elements - [disable\_sasl\_scram\_downgrade\_protection](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#disable-sasl-scram-downgrade-protection): New option to disable XEP-0474 - [negotiation\_timeout](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#negotiation-timeout): Increase default value from 30s to 2m - mod\_carboncopy: Teach how to interact with bind2 inline requests ### Other - ejabberdctl: Fix startup problem when having set `EJABBERD_OPTS` and logger options - ejabberdctl: Set EJABBERD\_OPTS back to `""`, and use previous flags as example - eldap: Change logic for `eldap tls_verify=soft` and `false` - eldap: Don’t set `fail_if_no_peer_cert` for eldap ssl client connections - Ignore hints when checking for chat states - mod\_mam: Support XEP-0424 Message Retraction - mod\_mam: Fix XEP-0425: Message Moderation with SQL storage - mod\_ping: Support XEP-0198 pings when stream management is enabled - mod\_pubsub: Normalize pubsub `max_items` node options on read - mod\_pubsub: PEP nodetree: Fix reversed logic in node fixup function - mod\_pubsub: Only care about PEP bookmarks options when creating node from scratch ### SQL - MySQL: Support `sha256_password` auth plugin - ejabberd\_sql\_schema: Use the first unique index as a primary key - Update SQL schema files for MAM’s XEP-0424 - New option [sql\_flags](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#sql-flags): right now only useful to enable `mysql_alternative_upsert` ### Installers and Container - Container: Add ability to ignore failures in execution of `CTL_ON_*` commands - Container: Update to Erlang/OTP 26.2, Elixir 1.16.1 and Alpine 3.19 - Container: Update this custom ejabberdctl to match the main one - make-binaries: Bump OpenSSL 3.2.1, Erlang/OTP 26.2.2, Elixir 1.16.1 - make-binaries: Bump many dependency versions ### Commands API - `print_sql_schema`: New command available in ejabberdctl command-line script - ejabberdctl: Rework temporary node name generation - ejabberdctl: Print argument description, examples and note in help - ejabberdctl: Document exclusive ejabberdctl commands like all the others - Commands: Add a new [muc\_sub](https://docs.ejabberd.im/developer/ejabberd-api/admin-tags/?ref=process-one.net#muc-sub) tag to all the relevant commands - Commands: Improve syntax of many commands documentation - Commands: Use list arguments in many commands that used separators - Commands: [set\_presence](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#set-presence): switch priority argument from string to integer - ejabberd\_commands: Add the command API version as [a tag vX](https://docs.ejabberd.im/developer/ejabberd-api/admin-tags/?ref=process-one.net#v1) - ejabberd\_ctl: Add support for list and tuple arguments - ejabberd\_xmlrpc: Fix support for restuple error response - mod\_http\_api: When no specific API version is requested, use the latest ### Compilation with Rebar3/Elixir/Mix - Fix compilation with Erlang/OTP 27: don’t use the reserved word ‘maybe’ - configure: Fix explanation of `--enable-group` option ([#4135](https://github.com/processone/ejabberd/issues/4135?ref=process-one.net)) - Add observer and runtime\_tools in releases when `--enable-tools` - Update “make translations” to reduce build requirements - Use Luerl 1.0 for Erlang 20, 1.1.1 for 21-26, and temporary fork for 27 - Makefile: Add `install-rel` and `uninstall-rel` - Makefile: Rename `make rel` to `make prod` - Makefile: Update `make edoc` to use ExDoc, requires mix - Makefile: No need to use `escript` to run rebar|rebar3|mix - configure: If `--with-rebar=rebar3` but rebar3 not system-installed, use local one - configure: Use Mix or Rebar3 by default instead of Rebar2 to compile ejabberd - ejabberdctl: Detect problem running iex or etop and show explanation - Rebar3: Include Elixir files when making a release - Rebar3: Workaround to fix protocol consolidation - Rebar3: Add support to compile Elixir dependencies - Rebar3: Compile explicitly our Elixir files when `--enable-elixir` - Rebar3: Provide proper path to `iex` - Rebar/Rebar3: Update binaries to work with Erlang/OTP 24-27 - Rebar/Rebar3: Remove Elixir as a rebar dependency - Rebar3/Mix: If `dev` profile/environment, enable tools automatically - Elixir: Fix compiling ejabberd as a dependency ([#4128](https://github.com/processone/ejabberd/issues/4128?ref=process-one.net)) - Elixir: Fix ejabberdctl start/live when installed - Elixir: Fix: `FORMATTER ERROR: bad return value` ([#4087](https://github.com/processone/ejabberd/issues/4087?ref=process-one.net)) - Elixir: Fix: Couldn’t find file `Elixir Hex API` - Mix: Enable stun by default when `vars.config` not found - Mix: New option `vars_config_path` to set path to `vars.config` ([#4128](https://github.com/processone/ejabberd/issues/4128?ref=process-one.net)) - Mix: Fix ejabberdctl iexlive problem locating iex in an OTP release ### Full Changelog [https://github.com/processone/ejabberd/compare/23.10…24.02](https://github.com/processone/ejabberd/compare/23.10...24.02?ref=process-one.net) ## ejabberd 24.02 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you’ve found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### WebPush support on your fluux.io instance URL: https://www.process-one.net/blog/webpush-support-on-your-fluux-io-instance/ Last updated: 2024-09-16T10:09:21.000Z FCM/APNs, enabling push notifications for [XMPP](https://xmpp.org/?ref=process-one.net) across various platforms. Now, our push notification capabilities are not limited to native mobile clients on iOS, MacOS and Android, but also extend to web applications on browsers like Safari, Chrome, Firefox [and more](https://caniuse.com/push-api?ref=process-one.net). This includes support for mobile versions of Safari and Chrome. This advancement broadens the scope for XMPP clients, offering new possibilities and a more extensive reach. Please also note that the Webpush support is also available to our customers using our on-premise ejabberd Business Edition. To enable it, go to your services in your [fluux.io console](https://fluux.io/services?ref=process-one.net), select “**Push Notifications**” and then “**\+ WebPush**” ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-01-at-23.29.57-1024x511.png) ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-01-at-23.33.41-1-1024x511.png) You will be prompted for an appid (typically the domain you want to enable WebPush on). For example here *fluux.io*. It will generate a [VAPID key](https://datatracker.ietf.org/doc/rfc8292/?ref=process-one.net) that will be used by ejabberd to sign the push notification sent to the user’s browser. ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-01-at-23.34.51-1-1024x511.png) Checking “**View Config**” will allow you to see the VAPID public key. It will be required to let the browser subscribe to notifications. Your website also needs to register a service worker that will be responsible for displaying the notification when a push is received. ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-01-at-23.37.54-config-1024x511.png) ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-02-at-18.22.00-1024x511.png) As an example, we provide a small ejabberd client to test the whole workflow. It is pre-populated with a test user and associated appid/key. ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-01-at-23.37.54-client-1024x511.png) ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-02-at-18.27.12-1024x511.png) The first step is to authenticate an XMPP user through your service. Then click “**Enable Push**“. ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-02-at-18.28.22-1024x511.png) ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-02-at-18.28.31-1024x511.png) It will ask authorization to enable push notification and create a subscription to FCM/Apple/Mozilla services. Then the XMPP client (using [strophe.js](https://strophe.im/strophejs/?ref=process-one.net)) will send a stanza to enable offline messaging. ejabberd will now send a notification to this entry point, which will send a push to the user’s browser. ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-02-at-18.28.47-1024x511.png) To trigger it, disconnect/close all opened XMPP sessions of your test user and send him a message from another test user. Your browser will display a notification from your website with the message snippet and its author. ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-02-at-18.31.53.png) ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-02-at-18.32.38-645x1024.png) Alternatively, you can check the test user and its associated devices: ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-01-at-23.37.54-devices-1024x511.png) ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-02-at-18.29.15-1024x511.png) and send a test notification: ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-03-at-22.16.55-1024x510.png) ![](https://www.process-one.net/wp-content/uploads/2024/01/Screenshot-2024-01-02-at-18.33.40-645x1024.png) ### Happy New Year: Celebrating 21 Years of Innovation with ejabberd URL: https://www.process-one.net/blog/happy-new-year-celebrating-21-years-of-innovation-with-ejabberd/ Last updated: 2024-09-16T10:12:02.000Z Time flies, and it’s hard to believe that ejabberd, our beloved open-source project, celebrated its 21st anniversary last November 16th! It’s a milestone that we’ve proudly highlighted over the years – remember the [4th](https://www.process-one.net/blog/ejabberd%5F4th%5Fbirthday/), [10th](https://www.process-one.net/blog/closed-protocols-come-and-go-ejabberd-and-xmpp-remains-10-years-of-success/), [18th](https://www.process-one.net/blog/happy-18th-birthday-ejabberd/), and [20th](https://www.process-one.net/blog/ejabberd-turns-20/) anniversaries? Well, 21 is just as significant, marking over two decades of innovation and community effort. In honor of this remarkable journey, we’ve launched a **new section** on the [ejabberd Docs](https://docs.ejabberd.im/get-started/?ref=process-one.net) site, showcasing a timeline of all ejabberd releases alongside their major advancements. This walk down memory lane is not just nostalgic, but a testament to continuous improvement and adaptation. Check out the [ejabberd roadmap](https://docs.ejabberd.im/archive/roadmap/?ref=process-one.net) to witness our evolutionary path. ## 2023: A Year of Significant Progress Reflecting on the past year, ejabberd has seen substantial growth and development with three key releases: - [**Version 23.01**](https://www.process-one.net/blog/ejabberd-23-01/)**:** Introduced an innovative MQTT bridge, offering users and devices the ability to use either XMPP, MQTT, or both using the same credentials. This feature leverages the same scalability & clustering features that made ejabberd famous, enhancing flexibility and user experience in communication protocols. - [**Version 23.04**](https://www.process-one.net/blog/ejabberd-23-04/)**:** Enhanced chatroom functionalities with support for [XEP-0425 (Message Moderation)](https://xmpp.org/extensions/xep-0425.html?ref=process-one.net) and [Real-Time Block List in MUC rooms](https://xmppbl.org/?ref=process-one.net), ensuring a safer, more controlled messaging environment. - [**Version 23.10**](https://www.process-one.net/blog/ejabberd-23-10/)**:** Focused on user experience improvements by adding support for [XEP-0402 (PEP Native Bookmarks)](https://xmpp.org/extensions/xep-0402.html?ref=process-one.net) and [XEP-0421: Occupant Id](https://xmpp.org/extensions/xep-0421.html?ref=process-one.net). ## Looking Ahead: What is Coming to ejabberd in Early 2024 As we step into the new year, our roadmap is already filled with exciting updates. The upcoming ejabberd releases are set to include: - [**RFC 9266**](https://www.rfc-editor.org/rfc/rfc9266?ref=process-one.net)**:** Introducing Channel Bindings for TLS 1.3, enhancing security and reliability. - [XEP-0388 (Extensible SASL Profile – SASL2)](https://xmpp.org/extensions/xep-0388.html?ref=process-one.net) - [XEP-0440 (SASL Channel-Binding Type Capability)](https://xmpp.org/extensions/xep-0440.html?ref=process-one.net): These updates are aimed at bolstering our authentication mechanisms. - [XEP-0386 (Bind 2)](https://xmpp.org/extensions/xep-0386.html?ref=process-one.net): This is going to reduce the connection time for clients. This is especially important if you are using XMPP to connect from a mobile network. - [XEP-0424 (Message Retraction)](https://xmpp.org/extensions/xep-0424.html?ref=process-one.net): Further enhancing user control over their own message, with the ability to ask for deletion. - [Automatic SQL Schema](https://www.process-one.net/blog/automatic-schema-update-in-ejabberd/) Creation and Update: Streamlining database management. - Commands [API Versioning](https://github.com/processone/ejabberd/pull/4118?ref=process-one.net): Ensuring better compatibility and flexibility for developers. - Support for Elixir 1.16. **But that’s not all.** In our continuous effort to share the advancements of ejabberd Business Edition with a wider audience, we have some exciting news for early 2024: - **Matrix Protocol Bridge:** Initially available exclusively for our supported customers, the Matrix protocol bridge will be integrated into the ejabberd Community Edition. This integration marks a significant step in expanding our interoperability and connectivity options. We will also be adding significant scalability improvements in ejabberd Business Edition: - **Database Sharding for Scalability:** Understanding the challenges of large-scale deployments, we are introducing database sharding features for our supported customers. This enhancement will significantly improve scalability, especially in scenarios where the database becomes a bottleneck. ## The “Invisible Leader” As we reflect on our milestones and look ahead, we owe immense gratitude to our community. Your support and feedback are the pillars of ejabberd’s success. Looking into 2024, we’re set to strengthen ejabberd’s presence and affirm ProcessOne’s role as the “invisible leader” in Instant Messaging. With exciting developments on the horizon, we’re eager to make the next year a landmark for ejabberd. Your continued feedback is vital as we forge ahead. Together, let’s shape 2024 into a remarkable year for ejabberd and our community. Thank you for being part of this journey. Here’s to an innovative 2024! ### Instant Messaging: Protocols are “Commons”, Let’s Take Them Seriously URL: https://www.process-one.net/blog/instant-messaging-protocols-are-commons-lets-take-them-seriously/ Last updated: 2024-09-16T10:17:12.000Z **TLDR;** **Thirty years after the advent of the first instant messaging services, we still haven’t reached the stage where instant messaging platforms can freely communicate with each other, as is the case with email. In 1999, the Jabber/XMPP protocol was created and standardized for this purpose by the Internet Engineering Task Force (IETF). Since then, proprietary messaging services have continuously leveraged the power of internet giants to dominate the market. Why do neither XMPP nor the more recent Matrix, which aimed to improve upon it, break through this barrier, when it’s clear that protocols must be open to enable exchange? Without this fundamental principle, the Internet itself wouldn’t exist.** **In the following article, I revisit how the French government recently promoted the instant messaging service Olvid and what this reveals about our approach to digital technology. It’s frustrating to see France promote a secure, yet proprietary messaging service that offers no progress in terms of interoperability, especially at a time when the European Union is striving to open up the sector by requiring all messaging services to be capable of intercommunication, through the *Digital Markets Act*.** **I conclude with reflections on our inability in Europe to collaborate on “commons,” our difficulty in building a foundation, an ecosystem that allows for healthy co-opetition, a blend of competition and collaboration, which is the only way to regain significance in the digital economy. Short-term political thinking forces our companies into an every-man-for-himself approach, preferring to dominate a small market rather than share a larger one.** ![](https://www.process-one.net/content/images/2024/09/Instant-Messaging-Protocols-are-Commons-Let-s-Take-Them-Seriously-1.jpg) **Today, perhaps, it’s time for a change?** Thirty years and counting since the emergence of the first instant messaging services, we still lack a universally accepted exchange protocol, as is the case with email. The Jabber protocol, later renamed XMPP (eXtensible Messaging and Presence Protocol) and made a standard, was born with the hope of breaking the proliferation of isolated silos like MSN, ICQ, Yahoo!, which did not communicate with each other. Today, other silos have emerged, but the problem persists: it is still impossible to exchange messages between accounts from different major messaging providers. Why? Let me tell you the story of a clumsy communication operation around a French messaging service, Olvid, which illustrates well the familiar patterns we often find ourselves stuck in. ## The French Government’s Endorsement of a Proprietary Messaging Service: A Closer Look I discovered the messaging service Olvid in late November 2023, following a flood of articles in the French press. I wondered how a company of 15 employees, created in 2019, had managed to get such press coverage. It was promoted directly by Prime Minister Elisabeth Borne: “Popular messaging applications like WhatsApp, Telegram or Signal have ‘security flaws’,” justified the office of Elisabeth Borne, who urged her ministers to download the French application.” ([Les Échos, November 30, 2023](https://www.lesechos.fr/tech-medias/hightech/messageries-les-ministres-sommes-dutiliser-lapplication-francaise-olvid-pour-communiquer-2038174?ref=process-one.net)). In November 2023, Matignon asked government members and ministerial offices to install this system on their phones and computers “to replace other instant messaging services to enhance the security of exchanges.” Then came the superlatives: “The most secure messaging service in the world” (Jean-Noël Barrot). “A step towards greater French sovereignty” (Elisabeth Borne). And it needs to be done quickly. Elisabeth Borne asked ministers to “take all necessary steps” to deploy Olvid in their ministry “by December 8, 2023, at the latest” ([Ouest France](https://www.ouest-france.fr/politique/les-ministeres-sommes-de-communiquer-desormais-via-lapp-francaise-olvid-e09e7316-5dd5-4449-a052-d28760b1f749?ref=process-one.net), November 29, 2023). Why Olvid? The articles I read on the subject remain relatively vague; I know mainly that it is certified by ANSII, the organization guaranteeing the state’s IT security. Yet, it’s far from the first secure messaging service I’ve come across, and it’s the first time I’ve heard of Olvid. What about other services and especially Signal, which is recognized worldwide for its security, backed by audits? Among secure messengers, the list is long: Signal, Threema, Wire, Berty, etc. So, what security flaws are we talking about? ### Signal Hits Back: A Strong Response to Security Claims Signal’s response was swift, with a direct and clear position from Meredith Whittaker, president of the Signal Foundation: > The French PM is mandating ministers use a small French messaging app. OK. But I’m alarmed that she’s claiming “security flaws” in Signal (et al) to justify the move. This claim is not backed by any evidence, and is dangerously misleading esp. coming from gov. > If you want to use a French product go for it! But don’t spread misinfo in the process. Signal is independently audited, open source, and our protocol has been tested for >10yrs. We are serious about responsible disclosure and we prioritize all reports to security@signal.org > [Numérama, December 1, 2023](https://www.numerama.com/tech/1576404-signal-accuse-la-france-de-dire-nimporte-quoi-sur-sa-messagerie-securisee.html?ref=process-one.net) ### Double Ratchet Regarding Olvid’s security, the main argument seems to be as follows: The system does not rely on centralized directories, operates without identifiers, which means no user account is hosted in the cloud. First, it seems to me that this is the principle of key-based authentication. Message routing is done solely based on a key, in the cryptographic sense. If it is lost, it’s impossible to recover the account. Nothing revolutionary, then; it’s cryptography, dating back to the encryption software PGP (Pretty Good Privacy) of the 1990s and even before. Then, such a system generally requires the physical exchange of public keys. Where Olvid seems to stand out is in the alternative ways proposed to simplify and lighten the burden of key exchange by meeting physically. This can work, first because the product is not free, so the user base is limited, where Signal, for example, offers a global platform and says it needs an identifier, the phone number to limit spam. Then, these alternative methods rely on mobile device management (MDM) tools, interfacing with an enterprise version of the Olvid server. In one way or another, this goes through a central point of distribution and reintroduces a weakness. It’s far from a completely decentralized protocol like what the team building the Berty messaging service is trying to do, for instance. Browsing their site to find the protocol, I admit I choked a bit on some mentions thrown a little freely on their site, for example, *Post Quantum Cryptography*, cryptography that resists quantum computing. It’s nice, it’s pleasant, but in practice, what’s the reality? I didn’t find more detail under this mention, but personally, being hit with such buzzwords makes me rather flee, as it smells of a commercial who got a bit carried away. But let’s assume, the Olvid team is composed of encryption experts. I skimmed their specifications, but I admit I’m not a mathematician, so who am I to judge their math formulas? What I do understand, however, is that almost all secure messaging systems, including Olvid, rely on the Double Ratchet algorithm, which was first introduced by… Signal. ## At the Heart of Messaging: The Critical Role of Protocols In terms of protocol, however, I am an expert. I have been working on instant messaging protocols since 1999\. And, it’s not beautiful… Olvid’s protocol is the antithesis of what I would like to see in an ambitious messaging protocol. It is a proprietary, ad hoc protocol, not based on any standard, minimalist for now, and condemns itself to reinventing the wheel, poorly. The burning question is, why not choose an open protocol that already works on a large scale, like XMPP, adding their value on top? The Internet protocol, TCP/IP, is open, all machines in the world can communicate, yet there are competing internet service providers. I am still looking for an answer. Because XMPP is too complex, some will say? I think any sufficiently advanced chat protocol tends to become a derivative of XMPP, less accomplished. Come on, why not even use Matrix, a competing protocol to my favorite? Apart from simple ignorance, I see no reason. Unless it’s to lock down the platform, perhaps? But, locking a communication protocol makes no sense. It’s replaying the battle of internet protocols, TCP/IP versus X.25\. A communication protocol is meant to be open and interoperable. Personally, I would invite Olvid to adopt a messaging standard. Let them turn to the W3C or IETF, to XMPP or MLS. These organizations do good work. And it’s a guarantee of sustainability and above all, of interoperability. We come to a very sore point. The European Commission, and therefore France as well, is discussing the implementation of the Digital Market Act. Among the points the European Union wants to impose is… the interoperability of instant messaging services. How can the French government promote a messaging solution that is not interoperable? And preferably standardized and open. I talked about Olvid’s proprietary protocol, which is actually more of an API (Application Programming Interface), that is, a document that describes how to automate certain functions of their server. What about the implementation? The client is open source (on iOS and Android), but seeing in their exchange interface calls to URLs named /Freetrial. This implies payment. I am not sure that Olvid would welcome the idea of compiling and deploying one’s own version of the client. That’s the principle of Open Source, but such an initiative could try to circumvent payments to Olvid. As anyway, no open-source server is available and the only one running is operated by Olvid, the client code is of little use. Especially since the client code is published by Olvid, but to what extent can we know if it is 100% identical to the version distributed in the iOS and Android app stores? We don’t really have a way of knowing. I know that Olvid promises one day to release the server as Open Source. What I’ve seen of the protocol, their business model, and what they say about their implementation, very tied to the Amazon infrastructure (an infrastructure managed by an American company, so much for sovereignty), makes me think that this will not happen, at least not for a very long time. I hope, of course, to be wrong. ## Toward Openness and Collaboration in Digital Communication In the meantime? I would really like us to be serious about instant messaging, that finally all players in the sector row in the same direction, those who work on open protocols, offering free servers and clients, that we build real collaboration, worthy of the construction of internet protocols, to build the foundation of a universal, open, open-source and truly interoperable messaging service. It doesn’t take much, to develop the culture of “coopetition,” collaboration around a common good between competing companies. - Photo by [Steve Johnson](https://unsplash.com/@steve%5Fj?utm%5Fcontent=creditCopyText&utm%5Fmedium=referral&utm%5Fsource=unsplash) on [Unsplash](https://unsplash.com/photos/gray-and-white-rolled-cable-hokONTrHIAQ?utm%5Fcontent=creditCopyText&utm%5Fmedium=referral&utm%5Fsource=unsplash) ### Automatic schema update in ejabberd URL: https://www.process-one.net/blog/automatic-schema-update-in-ejabberd/ Last updated: 2024-09-16T10:19:24.000Z Previously, if you were using ejabberd with an [external relational database](https://docs.ejabberd.im/admin/configuration/database/?ref=process-one.net#relational-databases), you might have to manually apply some schema changes that come with new features when you upgrade to a new ejabberd release. ejabberd can now handle this schema upgrade automatically. It can also create the schema on an empty database during a new deployment. It works with both [old and new schemas](https://docs.ejabberd.im/admin/configuration/database/?ref=process-one.net#default-and-new-schemas). This feature paves the way for more changes to our schema in the future. It is currently in beta testing, we recommend backing up your database before using it. To enable it in ejabberd 23.10, set this top-level option in your `ejabberd.yml` configuration file and restart ejabberd: ``` update_sql_schema: true ``` This is compatible with the following relational databases: - [MySQL](https://www.mysql.com/?ref=process-one.net) - [PostgreSQL](https://www.postgresql.org/?ref=process-one.net) - [SQLite](https://sqlite.org/?ref=process-one.net) Feel free to test it and report any problems on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### ejabberd 23.10 URL: https://www.process-one.net/blog/ejabberd-23-10/ Last updated: 2025-01-27T12:00:37.000Z A more detailed explanation of improvements and features: ## Added support for XEP-0402: PEP Native Bookmarks [XEP-0402: PEP Native Bookmarks](https://xmpp.org/extensions/xep-0402.html?ref=process-one.net) describes how to keep a list of chatroom bookmarks as PEP nodes on the PubSub service. That’s an improvement over [XEP-0048: Bookmark Storage](https://xmpp.org/extensions/xep-0048.html?ref=process-one.net) which described how to store in a single Private XML Storage or a single PEP node. [mod\_private](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod-private) now supports the bookmark conversion described in XEP-0402: ejabberd synchronizes XEP-0402 bookmarks, private storage bookmarks and XEP-0048 bookmarks. In this sense, the [bookmarks\_to\_pep](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#bookmarks-to-pep) command performs an initial synchronization of bookmarks, getting bookmarks from Private XML Storage and stores them in PEP nodes as described both in XEP-0048 and XEP-0402. ## New `mod_muc_occupantid` module with support for XEP-0421: Occupant Id [XEP-0421: Anonymous unique occupant identifiers for MUCs](https://xmpp.org/extensions/xep-0421.html?ref=process-one.net) is useful in anonymous MUC rooms, message correction and message retractions. Right now the only client found to support XEP-0421 is [Dino](https://dino.im/?ref=process-one.net), since version 0.4. ejabberd now implements XEP-0421 0.1.0 in [mod\_muc\_occupantid](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod-muc-occupantid). The module is quite simple and has no configurable options: just enabled it in the `modules` section in your `ejabberd.yml` configuration file and [restart](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#restart) ejabberd or [reload\_config](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#reload-config). ## New option `auth_external_user_exists_check` The new option [auth\_external\_user\_exists\_check](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#auth-external-user-exists-check) makes `user_check` hook work better with authentication methods that don’t have a way to determine if user exists. This happens, for example, in the case of jwt and cert based authentication. As result, enabling this option improves `mod_offline` and `mod_mam` handling of offline messages to those users. This reuses information stored by `mod_last` for this purpose. ## Improved offline messages handling when using authentication methods without users lists Authentication methods that manage users list outside of ejabberd, like for example JWT token or tls certificate authentication, had issue with processing of offline messages. Those methods didn’t have a way to tell if given user existed when user was not logged in, and that did block processing of offline messages, which were only performed for users that we know did exists. This release adds code that also consults data stored by `mod_last` for that purpose, and it should fix offline messages for users that were logged at least once before. ## Changes in `get_roster` command There are some changes in the result output of the [get\_roster](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get-roster) command defined in `mod_admin_extra`: - `ask` is renamed to `pending` - `group` is renamed to `groups` - the new `groups` is a list with all the group names - a contact that is in several groups is now listed only once, and the groups are properly listed. For example, let’s say that `admin@localhost` has two contacts: a contact is present in two groups (`group1` and `group2`), the other contact is only present in a group (`group3`). The [old get\_roster command in ejabberd 23.04](https://docs.ejabberd.im/archive/23%5F04/admin-api/?ref=process-one.net#get-roster) and previous versions was like: ``` $ ejabberdctl get_roster admin localhost jan@localhost jan none subscribe group1 jan@localhost jan none subscribe group2 tom@localhost tom none subscribe group3 ``` The new [get\_roster command](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#get-roster) in ejabberd 23.XX and newer versions returns as result: ``` $ ejabberdctl get_roster admin localhost jan@localhost jan none subscribe group1;group2 tom@localhost tom none subscribe group3 ``` Notice that the `ejabberdctl` command-line tool since now will represent list elements in results separated with `;` ## New `halt` command Until now there were two API commands to stop ejabberd: - [stop](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#stop) stops ejabberd gracefully, calling to stop each of its components (client sessions, modules, listeners, …) - [stop\_kindly](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#stop-kindly) first of all sends messages to all the online users and all the online MUC rooms, waits a few seconds, and then stops ejabberd gracefully. Those comands are useful when there’s an ejabberd running for many time, with many users connected, and you want to stop it. A new command is now added: [halt](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#halt), which abruptly stops the ejabberd node, without taking care to close gracefully any of its components. It also returns error code `1`. This command is useful if some problem is detected while ejabberd is starting. For example, it is now used in the [ecs](https://github.com/processone/docker-ejabberd/blob/master/ecs/README.md?ref=process-one.net) and the [ejabberd](https://github.com/processone/ejabberd/blob/master/CONTAINER.md?ref=process-one.net) container images when `CTL_ON_CREATE` or `CTL_ON_START` were provided and failed to execute correctly. See [docker-ejabberd#97](https://github.com/processone/docker-ejabberd/issues/97?ref=process-one.net) for details. ## MySQL driver improvements MySQL driver will now use prepared statements whenever possible, this should improve database load. This feature can be disabled with `sql_prepared_statement: false`. We also added alternative implementation of upsert that doesn’t use `replace ..` or `insert ... on conflict update`, as in some versions of MySQL this can lead to excessive deadlocks. We switch between implementations based on version but it’s possible to override version check by having: ``` sql_flags: - mysql_alternative_upsert ``` inside config file. ## New `unix_socket` listener option When defining a [listener](https://docs.ejabberd.im/admin/configuration/listen/?ref=process-one.net#listen-option), the `port` option can be a port number or a string in form `"unix:/path/to/socket"` to create and listen on a unix domain socket `/path/to/socket`. The new [unix\_socket](https://docs.ejabberd.im/admin/configuration/listen-options/?ref=process-one.net#unix-socket) listener option allows to customize some options of that unix socket file. The configurable options are: - `mode`: which should be an octal - `owner`: which should be an integer - `group`: which should be an integer Those values have no default: only when they are set, they are changed. Example configuration: ```yaml listen: - port: "unix:/tmp/asd/socket" unix_socket: mode: '0775' owner: 117 group: 135 ``` ## New `install_contrib_modules` top-level option The new [install\_contrib\_modules](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#install-contrib-modules) top-level option lets you declare a list of modules from [ejabberd-contrib](https://docs.ejabberd.im/developer/extending-ejabberd/modules/?ref=process-one.net#ejabberd-contrib) that will be installed automatically by ejabberd when it is being started. This option is read during ejabberd start or configuration reload. This option is equivalent to installing the module manually with the command `ejabberdctl module_install whatever`. It is useful when deploying ejabberd automatically with a configuration file that mentions a contrib module. For example, let’s enable and configure some modules from ejabberd-contrib, and use the new option to ensure they get installed, all of this the very first time ejabberd runs. Extract from `ejabberd.yml`: ```yaml ... install_contrib_modules: - mod_statsdx - mod_webadmin_config modules: mod_statsdx: hooks: true mod_webadmin_config: {} ... ``` The ejabberd.log file will show something like: ``` 2023-09-25 15:32:40.282446+02:00 [info] Loading configuration from _build/relive/conf/ejabberd.yml Module mod_statsdx has been installed and started. The mod_statsdx configuration in your ejabberd.yml is used. Module mod_webadmin_config has been installed and started. The mod_webadmin_config configuration in your ejabberd.yml is used. 2023-09-25 15:32:42.201199+02:00 [info] Configuration loaded successfully ... 2023-09-25 15:32:43.163099+02:00 [info] ejabberd 23.04.115 is started in the node ejabberd@localhost in 3.15s 2023-09-25 15:32:47.069875+02:00 [info] Reloading configuration from _build/relive/conf/ejabberd.yml 2023-09-25 15:32:47.100917+02:00 [info] Configuration reloaded successfully ``` ## New `notify_on` option in `mod_push` [mod\_push](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod-push) has a new option: `notify_on`, which possible values: - `all`: generate a notification on any kind of XMPP stanzas. This is the default value. - `messages`: notifications are only triggered for actual chat messages with a body text (or some encrypted payload). ## Add support to register nick in a room A nick can be registered in the MUC service since ejabberd 13.06, this prevents anybody else to use that nick in any room of that MUC service. Now ejabberd gets support to register a nick in a room, as described in XEP-0045 section [7.10 Registering with a Room](https://xmpp.org/extensions/xep-0045.html?ref=process-one.net#register) Registering a nick in the MUC service or in a room is mutually exclusive: – A nick that is registered in the service cannot be registered in any room, not even the original owner can register it. – Similarly, a nick registered in any room cannot be registered in the service. ## MUC room option `allow_private_messages` converted to `allowpm` Until ejabberd 23.04, MUC rooms had a configurable option called `allow_private_messages` with possible values `true` or `false`. Since ejabberd 23.10, that option is converted into `allowpm`, with possible values: - `anyone`: equivalent to `allow_private_messages=true` - `none`: equivalent to `allow_private_messages=false` - `participants` - `moderators` ## `gen_mod` API to simplify hooks and IQ handlers registration If you wrote some ejabberd module, you may want to update your module to the simplified `gen_mod` API. This is not mandatory, because the old way to do this is supported. Until now, erlang modules that implemented ejabberd’s `gen_mod` behaviour called `ejabberd_hooks:add` and `gen_iq_handler:add_iq_handler` in ther `start` functions. Similarly, in their `stop` function they called `ejabberd_hooks:delete` and `gen_iq_hanlder:remove_iq_handler`. Since ejabberd 23.10, there is an alternative way to do this: let your `start` function return `{ok, List}`, where `List` is a list of iq handlers and hooks that you want your module to register to. No need to unregister them in your `stop` function! How to change your module to the new API? See the changes done in `mod_adhoc.erl` in commit [60002fc](https://github.com/processone/ejabberd/commit/60002fc145c826c4ad5662bf08185bcbc6a26056?ref=process-one.net). ## MS SQL requirements To use the Microsoft SQL Server database, the `libtdsodbc` library is required, as explained in the corresponding section of the ejabberd Docs: [Configuration > Databases > Microsoft SQL Server](https://docs.ejabberd.im/admin/configuration/database/?ref=process-one.net#microsoft-sql-server) Since this release, the [ejabberd container image](https://github.com/processone/ejabberd/blob/master/CONTAINER.md?ref=process-one.net) includes this library. Please notice if you install ejabberd using the binary installers and want to use MS SQL: you must install the `libtdsodbc` libraries on your machine. It cannot be included in the ejabberd installer due to the nature of the odbc drivers being dynamic depending on the respective odbc backend in use. ## Erlang/OTP 20.0 or higher required This ejabberd release requires [Erlang/OTP](https://www.erlang.org/?ref=process-one.net) 20.0 or newer to compile and run, support for Erlang/OTP 19.3 is deprecated. If you are still using Erlang/OTP 19.3, please update to a more recent Erlang version. For example, the ejabberd binary installers and container images are using Erlang/OTP 26.1\. That requirement increase was announced almost a year ago, check more details in the [ejabberd 22.10 release announcement](https://www.process-one.net/blog/ejabberd-22-10/). If you are still using Erlang/OTP 19.3 and cannot update it right now, there’s still a possibility to compile ejabberd 23.10 with Erlang/OTP 19.3, but please notice: there is no guarantee or support that it will compile or run correctly. If interested, revert the changed line in the file `configure.ac` done in commit [d299b97](https://github.com/processone/ejabberd/commit/d299b97261ef78c9238317c3e057471f881751a9?ref=process-one.net) and recompile. ## Acknowledgments We would like to thank the contributions to the source code, documentation, and translation provided for this release by: - [Holger Weiß](https://github.com/weiss?ref=process-one.net) improvements in the installers and several modules - [Saarko](https://github.com/sando38?ref=process-one.net), improvements in the containers - EISST International Ltd for sponsoring work on `mod_push` new `notify_on` option - [Mr. EddX](https://hosted.weblate.org/user/MrEddX/?ref=process-one.net), new Bulgarian translation - [Wellington Uemura](https://hosted.weblate.org/user/wtuemura/?ref=process-one.net), updated the Portuguese (Brazil) translation - [Олександр Кревський](https://hosted.weblate.org/user/sasha135280/?ref=process-one.net), updated the Ukrainian translation - [Nautilusx](https://hosted.weblate.org/user/nautilusx/?ref=process-one.net), updated the German translation And also to all the people contributing in the ejabberd chatroom, issue tracker… ## Improvements in ejabberd Business Edition Customers of the [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/#getejabberd), in addition to all those improvements and bugfixes, also get: - Push: - Add support for [Webpush](https://www.w3.org/TR/push-api/?ref=process-one.net) - Various APNS & GCM fixes and optimizations - async calls to push backends - Improved error messages - Improve error detection and reconnection strategy - New `mod_push_logger` module to log push related events - [Matrix](https://matrix.org/?ref=process-one.net): - Add support for Matrix v10 rooms - Add SRV support in `mod_matrix_gw_s2s` - Misc: - Add `max_concurrent_connections` option to webhook - Add module for logging chat & jingle events in a separate file - Add [retraction handling](https://xmpp.org/extensions/xep-0424.html?ref=process-one.net) in MAM for p1db & dynamodb databases ## ChangeLog This is a more detailed list of changes in this ejabberd release: ### Compilation - Erlang/OTP: Raise the requirement to Erlang/OTP 20.0 as a minimum - CI: Update tests to Erlang/OTP 26 and recent Elixir - Move Xref and Dialyzer options from workflows to `rebar.config` - Add sections to `rebar.config` to organize its content - Dialyzer dirty workarounds because `re:mp()` is not an exported type - When installing module already configured, keep config as example - Elixir 1.15 removed support for `--app` - Elixir: Improve support to stop external modules written in Elixir - Elixir: Update syntax of function calls as recommended by Elixir compiler - Elixir: When building OTP release with mix, keep `ERLANG_NODE=ejabberd@localhost` - `ejabberdctl`: Pass `ERLANG_OPTS` when calling `erl` to parse the `INET_DIST_INTERFACE` ([#4066](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4066) ### Commands - `create_room_with_opts`: Fix typo and move examples to `args_example` ([#4080](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4080)) - `etop`: Let `ejabberdctl etop` work in a release (if `observer` application is available) - `get_roster`: Command now returns groups in a list instead of newlines ([#4088](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4088)) - `halt`: New command to halt ejabberd abruptly with an error status code - `ejabberdctl`: Fix calling ejabberdctl command with wrong number of arguments with Erlang 26 - `ejabberdctl`: Improve printing lists in results - `ejabberdctl`: Support `policy=user` in the help and return proper arguments - `ejabberdctl`: Document how to stop a debug shell: control+g - `ejabberdctl`: Support policy=user in the help and return proper arguments - `ejabberdctl`: Improve printing lists in results ### Container - Dockerfile: Add missing dependency for mssql databases - Dockerfile: Reorder stages and steps for consistency - Dockerfile: Use Alpine as base for `METHOD=package` - Dockerfile: Rename packages to improve compatibility - Dockerfile: Provide specific OTP and elixir vsn for direct compilation - Halt ejabberd if a command in `CTL_ON_` fails during ejabberd startup ### Core - `auth_external_user_exists_check`: New option ([#3377](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3377)) - `gen_mod`: Extend `gen_mod` API to simplify hooks and IQ handlers registration - `gen_mod`: Add shorter forms for `gen_mod` hook/`iq_handler` API - `gen_mod`: Update modules to the new `gen_mod` API - `install_contrib_modules`: New option to define contrib modules to install automatically - `unix_socket`: New listener option, useful when setting unix socket files ([#4059](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4059)) - `ejabberd_systemd`: Add a few debug messages - `ejabberd_systemd`: Avoid using `gen_server` timeout ([#4054](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4054))([#4058](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4058)) - `ejabberd_listener`: Increase default listen queue backlog value to 128, which is the default value on both Linux and FreeBSD ([#4025](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4025)) - OAuth: Handle `badpass` error message - When sending message on behalf of user, trigger `user_send_packet` ([#3990](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3990)) - Web Admin: In roster page move the `AddJID` textbox to top ([#4067](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4067)) - Web Admin: Show a warning when visiting webadmin with non-privileged account ([#4089](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4089)) ### Docs - Example configuration: clarify 5223 tls options; specify s2s shaper - Make sure that `policy=user` commands have `host` instead of `server` arg in docs - Improve syntax of many command descriptions for the Docs site - Move example Perl extauth script from ejabberd git to Docs site - Remove obsolete example files, and add link in Docs to the archived copies ### Installers (`make-binaries`) - Bump Erlang/OTP version to 26.1.1, and other dependencies - Remove outdated workaround - Don’t build Linux-PAM examples - Fix check for current Expat version - Apply minor simplifications - Don’t duplicate config entries - Don’t hard-code musl version - Omit unnecessary glibc setting - Set kernel version for all builds - Let curl fail on HTTP errors ### Modules - `mod_muc_log`: Add trailing backslash to URLs shown in disco info - `mod_muc_occupantid`: New module with support for XEP-0421 Occupant Id ([#3397](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3397)) - `mod_muc_rtbl`: Better error handling in ([#4050](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4050)) - `mod_private`: Add support for XEP-0402 PEP Native Bookmarks - `mod_privilege`: Don’t fail to edit roster ([#3942](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3942)) - `mod_pubsub`: Fix usage of `plugins` option, which produced `default_node_config` ignore ([#4070](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4070)) - `mod_pubsub`: Add `pubsub_delete_item` hook - `mod_pubsub`: Report support of `config-node-max` in pep - `mod_pubsub`: Relay pubsub iq queries to muc members without using bare jid ([#4093](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4093)) - `mod_pubsub`: Allow pubsub node owner to overwrite items published by other persons - `mod_push_keepalive`: Delay `wake_on_start` - `mod_push_keepalive`: Don’t let hook crash - `mod_push`: Add `notify_on` option - `mod_push`: Set `last-message-sender` to bare JID - `mod_register_web`: Make redirect to page that end with `/` ([#3177](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3177)) - `mod_shared_roster_ldap`: Don’t crash in `get_member_jid` on empty output ([#3614](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3614)) ### MUC - Add support to register nick in a room ([#3455](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3455)) - Convert `allow_private_message` MUC room option to `allowpm` ([#3736](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3736)) - Update xmpp version to send `roomconfig_changesubject` in disco#info ([#4085](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4085)) - Fix crash when loading room from DB older than ffa07c6, 23.04 - Fix support to retract a MUC room message - Don’t always store messages passed through `muc_filter_message` ([#4083](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4083)) - Pass also MUC room retract messages over the `muc_filter_message` ([#3397](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3397)) - Pass MUC room private messages over the `muc_filter_message` too ([#3397](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3397)) - Store the subject author JID, and run `muc_filter_message` when sending subject ([#3397](https://github.com/processone/ejabberd/issues/?ref=process-one.net#3397)) - Remove existing role information for users that are kicked from room ([#4035](https://github.com/processone/ejabberd/issues/?ref=process-one.net#4035)) - Expand rule “mucsub subscribers are members in members only rooms” to more places ### SQL - Add ability to force alternative upsert implementation in mysql - Properly parse mysql version even if it doesn’t have type tag - Use prepared statement with mysql - Add alternate version of mysql upsert - `ejabberd_auth_sql`: Reset scram fields when setting plain password - `mod_privacy_sql`: Fix return values from `calculate_diff` - `mod_privacy_sql`: Optimize `set_list` - `mod_privacy_sql`: Use more efficient way to calculate changes in `set_privacy_list` ### Full Changelog [https://github.com/processone/ejabberd/compare/23.04…23.10](https://github.com/processone/ejabberd/compare/23.04...23.10?ref=process-one.net) ## ejabberd 23.10 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you consider that you’ve found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### ejabberd 23.04 URL: https://www.process-one.net/blog/ejabberd-23-04/ Last updated: 2024-09-16T12:25:52.000Z - Many SQL database improvements - `mod_mam` support for [XEP-0425: Message Moderation](https://xmpp.org/extensions/xep-0425.html?ref=process-one.net) - New `mod_muc_rtbl`, Real-Time Block List for MUC rooms - Binaries use [Erlang/OTP](https://www.erlang.org/?ref=process-one.net) 25.3, and changes in containers A more detailed explanation of these topics and other features: ## Many improvements to SQL databases There are many improvements in the area of SQL databases (see [#3980](https://github.com/processone/ejabberd/pull/3980?ref=process-one.net) and [#3982](https://github.com/processone/ejabberd/pull/3982?ref=process-one.net)): - Added support for migrating MySQL and MS SQL to [new schema](https://docs.ejabberd.im/admin/configuration/database/?ref=process-one.net#default-and-new-schemas), fixed a long-standing bug, and many other improvements. - Regarding MS SQL, there are schema fixes, added support for `new` schema and the corresponding schema migration, along with other minor improvements and bugfixes. - The automated ejabberd tests now also run on updated schema databases, and support for running tests on MS SQL has been added. - and other minor SQL schema inconsistencies, removed unnecessary indexes and changed PostgreSQL SERIAL columns to BIGSERIAL columns. Please upgrade your existing SQL database, check the notes later in this document! ## Added `mod_mam` support for XEP-0425: Message Moderation [XEP-0425: Message Moderation](https://xmpp.org/extensions/xep-0425.html?ref=process-one.net) allows a Multi-User Chat (XEP-0045) moderator to moderate certain group chat messages, for example by removing them from the group chat history, as part of an effort to address and resolve issues such as message spam, inappropriate venue language, or revealing private personal information of others. It also allows moderators to correct a message on another user’s behalf, or flag a message as inappropriate, without having to retract it. Clients that currently support this XEP are [Gajim](https://gajim.org/?ref=process-one.net), [Converse.js](https://github.com/conversejs/converse.js?ref=process-one.net#supported-xmpp-extensions), [Monocles](https://monocles.de/more/?ref=process-one.net), and have read-only support [Poezio](https://poez.io/en/?ref=process-one.net) and [XMPP Web](https://github.com/nioc/xmpp-web?ref=process-one.net). ## New `mod_muc_rtbl` module This new module implements Real-Time Block List for MUC rooms. It works by monitoring remote pubsub nodes according to the specification described in [xmppbl.org](https://xmppbl.org/?ref=process-one.net). ## `captcha_url` option now accepts `auto` value In recent ejabberd releases, [captcha\_cmd](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#captcha-cmd) got support for macros (in [ejabberd 22.10](https://www.process-one.net/blog/ejabberd-22-10/)) and support for using modules (in [ejabberd 23.01](https://www.process-one.net/blog/ejabberd-23-01/)). Now [captcha\_url](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#captcha-url) gets an improvement: if set to `auto`, it tries to detect the URL automatically, taking into account the ejabberd configuration. This is now the default. This should be good enough in most cases, but manually setting the URL may be necessary when using port forwarding or very specific setups. ## Erlang/OTP 19.3 is deprecated This is the last ejabberd release with support for [Erlang/OTP](https://www.erlang.org/?ref=process-one.net) 19.3\. If you have not already done so, please upgrade to Erlang/OTP 20.0 or newer before the next ejabberd release. See the [ejabberd 22.10 release announcement](https://www.process-one.net/blog/ejabberd-22-10/) for more details. About the binary packages provided for ejabberd: - The binary installers and container images now use [Erlang/OTP](https://www.erlang.org/?ref=process-one.net) 25.3 and [Elixir](https://elixir-lang.org/?ref=process-one.net) 1.14.3. - The `mix`, `ecs` and `ejabberd` container images now use [Alpine](https://www.alpinelinux.org/?ref=process-one.net) 3.17. - The `ejabberd` container image now supports an alternative build method, useful to work around a problem in QEMU and Erlang 25 when building the image for the `arm64` architecture. ## Erlang node name in `ecs` container image The `ecs` container image is built using the files from [docker-ejabberd/ecs](https://github.com/processone/docker-ejabberd/tree/master/ecs?ref=process-one.net) and published in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net). This image generally gets only minimal fixes, no major or breaking changes, but in this release it got one change that requires administrator intervention. The Erlang node name is now fixed to `ejabberd@localhost` by default, instead of being variable based on the container hostname. If you previously allowed ejabberd to choose its node name (which was random), it will now create a new mnesia database instead of using the previous one: ```bash $ docker exec -it ejabberd ls /home/ejabberd/database/ ejabberd@1ca968a0301a ejabberd@localhost ... ``` A simple solution is to create a container that provides `ERLANG_NODE_ARG` with the old erlang node name, for example: ```bash docker run ... -e ERLANG_NODE_ARG=ejabberd@1ca968a0301a ``` or in `docker-compose.yml` ```yaml version: '3.7' services: main: image: ejabberd/ecs environment: - ERLANG_NODE_ARG=ejabberd@1ca968a0301a ``` Another solution is to [change the mnesia node name](https://github.com/processone/docker-ejabberd/tree/master/ecs?ref=process-one.net#change-mnesia-node-name) in the mnesia spool files. ## Other improvements to the `ecs` container image In addition to the previously mentioned change to the default erlang node name, the `ecs` container image has received other improvements: - For each commit to the docker-ejabberd repository that affects `ecs` and `mix` container images, those images are uploaded as artifacts and are available for download in the [corresponding runs](https://github.com/processone/docker-ejabberd/actions/workflows/tests.yml?ref=process-one.net). - When a new release is tagged in the docker-ejabberd repository, the image is automatically published to [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net), in addition to being manually published to the Docker Hub. - There are new sections in the `ecs` README file: [Clustering](https://github.com/processone/docker-ejabberd/tree/master/ecs?ref=process-one.net#clustering) and [Clustering Example](https://github.com/processone/docker-ejabberd/tree/master/ecs?ref=process-one.net#clustering-example). ## Documentation Improvements In addition to the usual improvements and fixes, some sections of the ejabberd documentation have been improved: - Database Configuration of [Microsoft SQL Server](https://docs.ejabberd.im/admin/configuration/database/?ref=process-one.net#microsoft-sql-server) - [ejabberd test suites](https://docs.ejabberd.im/developer/extending-ejabberd/testing/?ref=process-one.net) - [CAPTCHA](https://docs.ejabberd.im/admin/configuration/basic/?ref=process-one.net#captcha) ## Acknowledgments We would like to thank the following people for their contributions to the source code, documentation, and translation for this release: - [Stu Tomilson](https://github.com/nosnilmot?ref=process-one.net), many improvements to SQL - [Saarko](https://github.com/sando38?ref=process-one.net), container improvements and installer updates - [Silvério Santos](https://github.com/SantosSi?ref=process-one.net), for updating the Portuguese translation - [Blake Miller](https://github.com/based-a-tron?ref=process-one.net) And also to all the people who help solve doubts and problems in the ejabberd chatroom and issue tracker. ## Updating SQL Databases These notes allow you to apply the SQL database schema improvements in this ejabberd release to your existing SQL database. Please consider which database you are using and whether it is the [default or the new schema](https://docs.ejabberd.im/admin/configuration/database/?ref=process-one.net#default-and-new-schemas). ### PostgreSQL new schema: Fixes a long-standing bug in the new schema on PostgreSQL. The fix for all existing affected installations is the same: ```sql ALTER TABLE vcard_search DROP CONSTRAINT vcard_search_pkey; ALTER TABLE vcard_search ADD PRIMARY KEY (server_host, lusername); ``` ### PosgreSQL default or new schema: To convert columns to allow up to 2 billion rows in these tables. This conversion requires full table rebuilds and will take a long time if the tables already have many rows. Optional: This is not necessary if the tables will never grow large. ```sql ALTER TABLE archive ALTER COLUMN id TYPE BIGINT; ALTER TABLE privacy_list ALTER COLUMN id TYPE BIGINT; ALTER TABLE pubsub_node ALTER COLUMN nodeid TYPE BIGINT; ALTER TABLE pubsub_state ALTER COLUMN stateid TYPE BIGINT; ALTER TABLE spool ALTER COLUMN seq TYPE BIGINT; ``` ### PostgreSQL or SQLite default schema: ```sql DROP INDEX i_rosteru_username; DROP INDEX i_sr_user_jid; DROP INDEX i_privacy_list_username; DROP INDEX i_private_storage_username; DROP INDEX i_muc_online_users_us; DROP INDEX i_route_domain; DROP INDEX i_mix_participant_chan_serv; DROP INDEX i_mix_subscription_chan_serv_ud; DROP INDEX i_mix_subscription_chan_serv; DROP INDEX i_mix_pam_us; ``` ### PostgreSQL or SQLite new schema: ```sql DROP INDEX i_rosteru_sh_username; DROP INDEX i_sr_user_sh_jid; DROP INDEX i_privacy_list_sh_username; DROP INDEX i_private_storage_sh_username; DROP INDEX i_muc_online_users_us; DROP INDEX i_route_domain; DROP INDEX i_mix_participant_chan_serv; DROP INDEX i_mix_subscription_chan_serv_ud; DROP INDEX i_mix_subscription_chan_serv; DROP INDEX i_mix_pam_us; ``` And now add index that might be missing In PostgreSQL: ```sql CREATE INDEX i_push_session_sh_username_timestamp ON push_session USING btree (server_host, username, timestamp); ``` In SQLite: ```sql CREATE INDEX i_push_session_sh_username_timestamp ON push_session (server_host, username, timestamp); ``` ### MySQL default schema: ```sql ALTER TABLE rosterusers DROP INDEX i_rosteru_username; ALTER TABLE sr_user DROP INDEX i_sr_user_jid; ALTER TABLE privacy_list DROP INDEX i_privacy_list_username; ALTER TABLE private_storage DROP INDEX i_private_storage_username; ALTER TABLE muc_online_users DROP INDEX i_muc_online_users_us; ALTER TABLE route DROP INDEX i_route_domain; ALTER TABLE mix_participant DROP INDEX i_mix_participant_chan_serv; ALTER TABLE mix_participant DROP INDEX i_mix_subscription_chan_serv_ud; ALTER TABLE mix_participant DROP INDEX i_mix_subscription_chan_serv; ALTER TABLE mix_pam DROP INDEX i_mix_pam_u; ``` ### MySQL new schema: ```sql ALTER TABLE rosterusers DROP INDEX i_rosteru_sh_username; ALTER TABLE sr_user DROP INDEX i_sr_user_sh_jid; ALTER TABLE privacy_list DROP INDEX i_privacy_list_sh_username; ALTER TABLE private_storage DROP INDEX i_private_storage_sh_username; ALTER TABLE muc_online_users DROP INDEX i_muc_online_users_us; ALTER TABLE route DROP INDEX i_route_domain; ALTER TABLE mix_participant DROP INDEX i_mix_participant_chan_serv; ALTER TABLE mix_participant DROP INDEX i_mix_subscription_chan_serv_ud; ALTER TABLE mix_participant DROP INDEX i_mix_subscription_chan_serv; ALTER TABLE mix_pam DROP INDEX i_mix_pam_us; ``` Add index that might be missing: ```sql CREATE INDEX i_push_session_sh_username_timestamp ON push_session (server_host, username(191), timestamp); ``` ### MS SQL ```sql DROP INDEX [rosterusers_username] ON [rosterusers]; DROP INDEX [sr_user_jid] ON [sr_user]; DROP INDEX [privacy_list_username] ON [privacy_list]; DROP INDEX [private_storage_username] ON [private_storage]; DROP INDEX [muc_online_users_us] ON [muc_online_users]; DROP INDEX [route_domain] ON [route]; go ``` MS SQL schema was missing some tables added in earlier versions of ejabberd: ```sql CREATE TABLE [dbo].[mix_channel] ( [channel] [varchar] (250) NOT NULL, [service] [varchar] (250) NOT NULL, [username] [varchar] (250) NOT NULL, [domain] [varchar] (250) NOT NULL, [jid] [varchar] (250) NOT NULL, [hidden] [smallint] NOT NULL, [hmac_key] [text] NOT NULL, [created_at] [datetime] NOT NULL DEFAULT GETDATE() ) TEXTIMAGE_ON [PRIMARY]; CREATE UNIQUE CLUSTERED INDEX [mix_channel] ON [mix_channel] (channel, service) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); CREATE INDEX [mix_channel_serv] ON [mix_channel] (service) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); CREATE TABLE [dbo].[mix_participant] ( [channel] [varchar] (250) NOT NULL, [service] [varchar] (250) NOT NULL, [username] [varchar] (250) NOT NULL, [domain] [varchar] (250) NOT NULL, [jid] [varchar] (250) NOT NULL, [id] [text] NOT NULL, [nick] [text] NOT NULL, [created_at] [datetime] NOT NULL DEFAULT GETDATE() ) TEXTIMAGE_ON [PRIMARY]; CREATE UNIQUE INDEX [mix_participant] ON [mix_participant] (channel, service, username, domain) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); CREATE INDEX [mix_participant_chan_serv] ON [mix_participant] (channel, service) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); CREATE TABLE [dbo].[mix_subscription] ( [channel] [varchar] (250) NOT NULL, [service] [varchar] (250) NOT NULL, [username] [varchar] (250) NOT NULL, [domain] [varchar] (250) NOT NULL, [node] [varchar] (250) NOT NULL, [jid] [varchar] (250) NOT NULL ); CREATE UNIQUE INDEX [mix_subscription] ON [mix_subscription] (channel, service, username, domain, node) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); CREATE INDEX [mix_subscription_chan_serv_ud] ON [mix_subscription] (channel, service, username, domain) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); CREATE INDEX [mix_subscription_chan_serv_node] ON [mix_subscription] (channel, service, node) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); CREATE INDEX [mix_subscription_chan_serv] ON [mix_subscription] (channel, service) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); CREATE TABLE [dbo].[mix_pam] ( [username] [varchar] (250) NOT NULL, [channel] [varchar] (250) NOT NULL, [service] [varchar] (250) NOT NULL, [id] [text] NOT NULL, [created_at] [datetime] NOT NULL DEFAULT GETDATE() ) TEXTIMAGE_ON [PRIMARY]; CREATE UNIQUE CLUSTERED INDEX [mix_pam] ON [mix_pam] (username, channel, service) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); go ``` MS SQL also had some incompatible column types: ```sql ALTER TABLE [dbo].[muc_online_room] ALTER COLUMN [node] VARCHAR (250); ALTER TABLE [dbo].[muc_online_room] ALTER COLUMN [pid] VARCHAR (100); ALTER TABLE [dbo].[muc_online_users] ALTER COLUMN [node] VARCHAR (250); ALTER TABLE [dbo].[pubsub_node_option] ALTER COLUMN [name] VARCHAR (250); ALTER TABLE [dbo].[pubsub_node_option] ALTER COLUMN [val] VARCHAR (250); ALTER TABLE [dbo].[pubsub_node] ALTER COLUMN [plugin] VARCHAR (32); go ``` … and `mqtt_pub` table was incorrectly defined in old schema: ```sql ALTER TABLE [dbo].[mqtt_pub] DROP CONSTRAINT [i_mqtt_topic_server]; ALTER TABLE [dbo].[mqtt_pub] DROP COLUMN [server_host]; ALTER TABLE [dbo].[mqtt_pub] ALTER COLUMN [resource] VARCHAR (250); ALTER TABLE [dbo].[mqtt_pub] ALTER COLUMN [topic] VARCHAR (250); ALTER TABLE [dbo].[mqtt_pub] ALTER COLUMN [username] VARCHAR (250); CREATE UNIQUE CLUSTERED INDEX [dbo].[mqtt_topic] ON [mqtt_pub] (topic) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); go ``` … and `sr_group` index/PK was inconsistent with other DBs: ```sql ALTER TABLE [dbo].[sr_group] DROP CONSTRAINT [sr_group_PRIMARY]; CREATE UNIQUE CLUSTERED INDEX [sr_group_name] ON [sr_group] ([name]) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); go ``` ## ChangeLog ### General - New `s2s_out_bounce_packet` hook - Re-allow anonymous connection for connection without client certificates ([#3985](https://github.com/processone/ejabberd/issues/3985?ref=process-one.net)) - Stop `ejabberd_system_monitor` before stopping node - `captcha_url` option now accepts `auto` value, and it’s the default - `mod_mam`: Add support for XEP-0425: Message Moderation - `mod_mam_sql`: Fix problem with results of mam queries using rsm with max and before - `mod_muc_rtbl`: New module for Real-Time Block List for MUC rooms ([#4017](https://github.com/processone/ejabberd/issues/4017?ref=process-one.net)) - `mod_roster`: Set roster name from XEP-0172, or the stored one ([#1611](https://github.com/processone/ejabberd/issues/1611?ref=process-one.net)) - `mod_roster`: Preliminary support to store extra elements in subscription request ([#840](https://github.com/processone/ejabberd/issues/840?ref=process-one.net)) - `mod_pubsub`: Pubsub xdata fields `max_item/item_expira/children_max` use `max` not `infinity` - `mod_vcard_xupdate`: Invalidate `vcard_xupdate` cache on all nodes when vcard is updated ### Admin - `ext_mod`: Improve support for loading `*.so` files from `ext_mod` dependencies - Improve output in `gen_html_doc_for_commands` command - Fix ejabberdctl output formatting ([#3979](https://github.com/processone/ejabberd/issues/3979?ref=process-one.net)) - Log HTTP handler exceptions ### MUC - New command `get_room_history` - Persist `none` role for outcasts - Try to populate room history from mam when unhibernating - Make `mod_muc_room:set_opts` process persistent flag first - Allow passing affiliations and subscribers to `create_room_with_opts` command - Store state in db in `mod_muc:create_room()` - Make subscribers members by default ### SQL schemas - Fix a long standing bug in new schema migration - `update_sql` command: Many improvements in new schema migration - `update_sql` command: Add support to migrate MySQL too - Change PostgreSQL SERIAL to BIGSERIAL columns - Fix minor SQL schema inconsistencies - Remove unnecessary indexes - New SQL schema migrate fix ### MS SQL - MS SQL schema fixes - Add `new` schema for MS SQL - Add MS SQL support for new schema migration - Minor MS SQL improvements - Fix MS SQL error caused by `ORDER BY` in subquery ### SQL Tests - Add support for running tests on MS SQL - Add ability to run tests on upgraded DB - Un-deprecate `ejabberd_config:set_option/2` - Use python3 to run `extauth.py` for tests - Correct README for creating test docker MS SQL DB - Fix TSQLlint warnings in MSSQL test script ### Testing - Fix Shellcheck warnings in shell scripts - Fix Remark-lint warnings - Fix Prospector and Pylint warnings in test `extauth.py` - Stop testing ejabberd with Erlang/OTP 19.3, as Github Actions no longer supports ubuntu-18.04 - Test only with oldest OTP supported (20.0), newest stable (25.3) and bleeding edge (26.0-rc2) - Upload Common Test logs as artifact in case of failure ### `ecs` container image - Update Alpine to 3.17 to get Erlang/OTP 25 and Elixir 1.14 - Add `tini` as runtime init - Set `ERLANG_NODE` fixed to `ejabberd@localhost` - Upload images as artifacts to Github Actions - Publish tag images automatically to ghcr.io ### `ejabberd` container image - Update Alpine to 3.17 to get Erlang/OTP 25 and Elixir 1.14 - Add `METHOD` to build container using packages ([#3983](https://github.com/processone/ejabberd/issues/3983?ref=process-one.net)) - Add `tini` as runtime init - Detect runtime dependencies automatically - Remove unused Mix stuff: ejabberd script and static COOKIE - Copy captcha scripts to `/opt/ejabberd-*/lib` like the installers - Expose only `HOME` volume, it contains all the required subdirs - ejabberdctl: Don’t use `.../releases/COOKIE`, it’s no longer included ### Installers - make-binaries: Bump versions, e.g. erlang/otp to 25.3 - make-binaries: Fix building with erlang/otp 25.x - make-packages: Fix for installers workflow, which didn’t find lynx ### Full Changelog [https://github.com/processone/ejabberd/compare/23.01…23.04](https://github.com/processone/ejabberd/compare/23.01...23.04?ref=process-one.net) ## ejabberd 23.04 download & feedback As usual, the release is tagged in the git source repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available on the [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To verify the `*.asc` signature files, see [How to verify the integrity of ProcessOne downloads](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations such as the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The `ecs` container image is available in [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net) and [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs?ref=process-one.net). The alternative `ejabberd` container image is available in [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you think you’ve found a bug, please search or file a bug report at [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### ejabberd 23.01 URL: https://www.process-one.net/blog/ejabberd-23-01/ Last updated: 2024-09-16T12:28:14.000Z A more detailed explanation of those topics and other features: ## Erlang/OTP 19.3 discouraged Remember that support for Erlang/OTP 19.3 is discouraged, and will be removed in a future release. Please upgrade to Erlang/OTP 20.0 or newer. Check more details in the [ejabberd 22.10 release announcement](https://www.process-one.net/blog/ejabberd-22-10/). ## New MQTT bridge This new module allows synchronizing topic changes between local and remote servers. It can be configured to replicate local changes to remote server, or can subscribe to topics on remote server and update local copies when they change. When connecting to a remote server you can use native or websocket encapsulated protocol, and you can connect using both v4 and v5 protocol. It can authenticate using username/password pairs or with client TLS certificates. ## New Hooks Regarding MQTT support, there are several new hooks: - `mqtt_publish`: New hook for MQTT publish event - `mqtt_subscribe` and `mqtt_unsubscribe`: New hooks for MQTT subscribe & unsubscribe events ## New option `log_modules_fully` The [loglevel](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#loglevel) top-level option specifies the verbosity of log files generated by ejabberd. If you want some specific modules to log everything, independently from whatever value you have configured in `loglevel`, now you can use the new [log\_modules\_fully](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#log%5Fmodules%5Ffully) option. For example, if you are investigating some problem in `ejabberd_sm` and `mod_client_state`: ```yaml loglevel: warning log_modules_fully: [ejabberd_sm, mod_client_state] ``` (This option works only on systems with Erlang 22 or newer). ## Changes in option `outgoing_s2s_families` The [outgoing\_s2s\_families](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#outgoing-s2s-families) top-level option specifies which address families to try, in what order. The default value has now been changed to try IPv6 first, as servers are within data centers where IPv6 is more commonly enabled (contrary to clients). And if it’s not present, then it’ll just fall back to IPv4. By the way, this option is obsolete and irrelevant when using ejabberd 23.01 and Erlang/OTP 22, or newer versions of them. ## Changes in option `captcha_cmd` The [captcha\_cmd](https://docs.ejabberd.im/admin/configuration/toplevel/?ref=process-one.net#captcha-cmd) top-level option specifies the full path to a script that can generate a CAPTCHA image. Now this option may specify an Erlang module name, which should implement a function to generate a CAPTCHA image. ejabberd does not include any such module, but there are two available in the ejabberd-contrib repository that you can install and try: [mod\_ecaptcha](https://github.com/processone/ejabberd-contrib/tree/master/mod%5Fecaptcha?ref=process-one.net) and [mod\_captcha\_rust](https://github.com/processone/ejabberd-contrib/tree/master/mod%5Fcaptcha%5Frust?ref=process-one.net). ## DOAP file The protocols implemented or supported by ejabberd are defined in the corresponding source code modules since ejabberd 15.06\. Until now, only the XEP number and supported version were tracked. Since now, it’s possible to document what ejabberd version first implemented it, the implementation status and an arbitrary comment. That information until now was only used by the script [tools/check\_xep\_versions.sh](https://github.com/processone/ejabberd/blob/master/tools/check%5Fxep%5Fversions.sh?ref=process-one.net). A new script is added, [tools/generate-doap.sh](https://github.com/processone/ejabberd/blob/master/tools/generate-doap.sh?ref=process-one.net), to generate a DOAP file with that information. A new target is added to Makefile: `make doap`. And that DOAP file is now published as `ejabberd.doap` in the git repository. That file is read by the XMPP.org website to show ejabberd’s protocols, see [XMPP Servers: ejabberd](https://xmpp.org/software/servers/ejabberd/?ref=process-one.net). ## VSCode Support for Visual Studio Code and variants is vastly improved. Thanks to the [Erlang LS VSCode extension](https://github.com/erlang-ls/vscode?ref=process-one.net), the ejabberd git repository includes support for developing, compiling and debugging ejabberd with Visual Studio Code, VSCodium, Coder’s code-server and Github Codespaces. See more details in the [ejabberd Docs: VSCode](https://docs.ejabberd.im/developer/vscode/?ref=process-one.net) page. ## ChangeLog ### General - Add `misc:uri_parse/2` to allow declaring default ports for protocols - CAPTCHA: Add support to define module instead of path to script - Clustering: Handle `mnesia_system_event mnesia_up` when other node joins this ([#3842](https://github.com/processone/ejabberd/issues/3842?ref=process-one.net)) - ConverseJS: Don’t set i18n option because Converse enforces it instead of browser lang ([#3951](https://github.com/processone/ejabberd/issues/3951?ref=process-one.net)) - ConverseJS: Try to redirect access to files `mod_conversejs` to CDN when there is no local copies - ext\_mod: compile C files and install them in ejabberd’s `priv` - ext\_mod: Support to get module status from Elixir modules - make-binaries: reduce log output - make-binaries: Bump zlib version to 1.2.13 - MUC: Don’t store mucsub presence events in offline storage - MUC: `hibernation_time` is not an option worth storing in room state ([#3946](https://github.com/processone/ejabberd/issues/3946?ref=process-one.net)) - Multicast: Jid format when `multicastc` was cached ([#3950](https://github.com/processone/ejabberd/issues/3950?ref=process-one.net)) - mysql: Pass `ssl` options to mysql driver - pgsql: Do not set `standard_conforming_strings` to `off` ([#3944](https://github.com/processone/ejabberd/issues/3944?ref=process-one.net)) - OAuth: Accept `jid` as a HTTP URL query argument - OAuth: Handle when client is not identified - PubSub: Expose the `pubsub#type` field in `disco#info` query to the node ([#3914](https://github.com/processone/ejabberd/issues/3914?ref=process-one.net)) - Translations: Update German translation ### Admin - `api_permissions`: Fix option crash when doesn’t have `who:` section - `log_modules_fully`: New option to list modules that will log everything - `outgoing_s2s_families`: Changed option’s default to IPv6, and fall back to IPv4 - Fix bash completion when using Relive or other install methods - Fix portability issue with some shells ([#3970](https://github.com/processone/ejabberd/issues/3970?ref=process-one.net)) - Allow admin command to subscribe new users to `members_only` rooms - Use alternative `split/2` function that works with Erlang/OTP as old as 19.3 - Silent warning in OTP24 about not specified `cacerts` in SQL connections - Fix compilation warnings with Elixir 1.14 ### DOAP - Support extended `-protocol` erlang attribute - Add extended RFCs and XEP details to some protocol attributes - `tools/generate-doap.sh`: New script to generate DOAP file, add `make doap` ([#3915](https://github.com/processone/ejabberd/issues/3915?ref=process-one.net)) - `ejabberd.doap`: New DOAP file describing ejabberd supported protocols ### MQTT - Add MQTT bridge module - Add support for certificate authentication in MQTT bridge - Implement reload in MQTT bridge - Add support for websockets to MQTT bridge - Recognize ws5/wss5 urls in MQTT bridge - `mqtt_publish`: New hook for MQTT publish event - `mqtt_(un)subscribe`: New hooks for MQTT subscribe & unsubscribe events ### VSCode - Improve `.devcontainer` to use use devcontainer image and `.vscode` - Add `.vscode` files to instruct VSCode how to run ejabberd - Add Erlang LS default configuration - Add Elvis default configuration ### Full Changelog [https://github.com/processone/ejabberd/compare/22.10…23.01](https://github.com/processone/ejabberd/compare/22.10...23.01?ref=process-one.net) ## ejabberd 23.01 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The Docker image is in [Docker Hub](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net), and there’s an alternative Container image in [GitHub Packages](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you suspect that you’ve found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Federate the world — Best wishes from ProcessOne URL: https://www.process-one.net/blog/federate-the-world-best-wishes-from-processone/ Last updated: 2024-09-16T12:30:14.000Z This time of the year is the moment to ponder what is coming. After three very strange years, I am sure you are witnessing as we do that something is happening. A transformation process is at work in the technology industry. The motto this year is independence. As always, in almost 20 years of existence we are seeing a swing of the pendulum and a new trend in which decentralization and federation are coming back with strength. We see new services emerging, using our realtime tools, in places where companies had been using big tech company infrastructure in the past. This is a time in which small niche players like ProcessOne are getting a boost. This is an exciting time, because it is a moment where opportunities can be seized in a kind of a reshuffle of the power at play in the IT world. The myth of Silicon Valley is dissolving, the fragility of iconic tech companies is becoming apparent. Companies of various sizes are taking their chance and ProcessOne is helping other companies build those independent services. Decentralization through the federation is at the heart of the XMPP communication protocol and is critical to building interoperable systems. With our ejabberd software, we are uniquely positioned to take advantage of this move, on XMPP and all the protocols we implement (XMPP, MQTT, SIP and Matrix). Please, contact us if you think we can help you ride the wave and address your challenges in the coming year. Thanks for working with us ! My best regards, — Mickaël Rémond ### Hello Fediverse ! URL: https://www.process-one.net/blog/hello-fediverse/ Last updated: 2024-09-16T12:31:31.000Z Just a quick note to let you know that we have suspended our activity on Twitter. It has been in the past a good place to gather with similarly minded technical people. We feel this is not the case anymore. So, we moved our social network presence in the Fediverse ! You can follow ProcessOne on our Mastodon instance: [@ProcessOne@process-one.net](https://social.process-one.net/@ProcessOne?ref=process-one.net) I (Mickaël Rémond) have my tech account there as well: [@mremond@process-one.net](https://social.process-one.net/@mremond?ref=process-one.net) If you do not have yet an account supporting ActivityPub, you can explore an aggregate of our posts and musing on this page: [https://social.process-one.net/public/local](https://social.process-one.net/public/local?ref=process-one.net) Please join the conversation and let’s talk about federating the world ! ### ejabberd turns 20 URL: https://www.process-one.net/blog/ejabberd-turns-20/ Last updated: 2024-09-16T12:34:14.000Z This is a long time, even at the scale of Internet. And yet, what ejabberd represents has not always been obvious. It took us a long time to realize what was so important about ejabberd. Why have we been developing it for 20 years? Why are we pushing it further even today? What makes it so special? ejabberd is a scalable messaging server. That sums it all and that does not do justice to this critical piece of the Internet infrastructure. Sure, it is known to be the most scalable XMPP server, so scalable that it was used as a building brick to build Whatsapp messaging service. This is something that we have always been proud of, something you can easily brag about when meeting your friends. But is that just it? Of course not. Today, with the troubles at Twitter, something appeared clearly. ejabberd is important because it helped build much more than Whatsapp or any other big name high-profile projects we have built. It is important because it makes people communicate, in a federated way. It is important because it implements open protocols, and now several of them: XMPP, MQTT, SIP and now Matrix. # It’s about federation ejabberd is about federation. It is helping people on different servers, domains, companies, communities or even countries chatting together. And today even more than 20 years ago, it really matters. We have built ejabberd for 20 years, because it is a critical building brick of what makes the Internet exists. Openness, interoperability, federation. It is one of the few software that prosper outside of the spotlights and make the Internet what it is, along for example with web and mail servers. This is something we are pondering as we are thinking about the next steps, the next 20 years. But deep down, we know for sure, what we are about. ejabberd is about federation. You will read more from us here soon. It is a tradition. No birthday celebration speech is complete without looking back at the past. It is hard to track all ejabberd usage, but we know that ejabberd empowers more than a billion users. Not bad for a piece of code we wrote. Trillions of messages went through our lines of code. As mentioned in [this post ten years ago](https://www.process-one.net/blog/closed-protocols-come-and-go-ejabberd-and-xmpp-remains-10-years-of-success/): > Closed protocols come and go – ejabberd and XMPP remains Happy 20th birthday, ejabberd! # Brief timeline The very first public commit in ejabberd’s source code was done by Alexey Shchepin the 16th November of 2002\. That was in the Jabber.ru CVS server. Later when that machine had technical problems, the development code moved to [JabberStudio](https://web.archive.org/web/20031128232939/http://jabberstudio.org/) CVS. The first official ejabberd release was [ejabberd 0.5 in November 2003](http://lists.jabber.ru/pipermail/ejabberd/2003-November/000052.html?ref=process-one.net). The [ejabberd home page](https://www.ejabberd.im/files/site/old-website/ejabberd-0.5.html?ref=process-one.net) at that time was a simple HTML. It’s also worth checking the early stage of the [Ejabberd Installation and Operation Guide](https://web.archive.org/web/20030409163941/http://ejabberd.jabberstudio.org/guide.html). Notice this first ejabberd logo represented a frog-like animal sitting on a “Jabber globe bulb,” with bat wings, dangerous-looking cogs, and an Erlang suit. After the 0.7.5 release in October 2004, ejabberd home page moved from JabberStudio to [ejabberd.jabber.ru](https://web.archive.org/web/20050730000817/http://ejabberd.jabber.ru/), and the bug tracker to Jabber.ru’s Bugzilla. For this Drupal site, the logo changed to a hedgehog, and that would remain ten years until the final [website and logo update in 2015](https://www.process-one.net/blog/revamped-ejabberd-im-website-logo/). At the beginning of 2005, JabberStudio CVS had technical difficulties and the development code moved to ProcessOne SVN. Notice that ProcessOne contracted Alexey to work in J-EAI, a project based in ejabberd specially designed for some business usages, and later extended that relationship to ejabberd. In February 2005 the source code repository moved from SVN to Git, and the [bug tracker to JIRA](https://www.process-one.net/blog/ejabberd%5Fbug%5Ftracker%5Fopen%5Ffor%5Fregistration/). Around October 2010 the source code repository and the bug tracker were finally moved to GitHub. From around that time, there’s an [interview to Alexey Shchepin](https://www.ejabberd.im/interview-aleksey/index.html?ref=process-one.net) which covers the initial concept and years of ejabberd development. By the way, there was [another interview two years ago](https://www.process-one.net/blog/interview-with-alexey-shchepin-creator-of-ejabberd/). The ejabberd code base got a relevant massive change with the data binarization (use Erlang binaries instead of Erlang strings for data representation) in March 2013, which jumped ejabberd version from 2.1.12 to 13.03. The next years followed another major source code change: [the movement](https://www.process-one.net/blog/ejabberd-and-dependencies-major-set-of-open-source-repositories/) of many C/C++ code to independent external libraries. Today, ejabberd is not just about XMPP. Even if it is mostly know for its great XMPP support, it also supports several other protocols: – SIP support to connect SIP phone was added in 2014 (see [ejabberd 14.05](https://www.process-one.net/blog/ejabberd-community-14-05/)) – Support for MQTT protocol, to better support Internet of Things use cases, was [added initially in the Business Edition](https://www.process-one.net/blog/first-ever-mqtt-and-xmpp-dual-protocol-server-ejabberd-business-edition/), and some months later [added to the Community Server 19.02](https://www.process-one.net/blog/ejabberd-19-02-the-mqtt-edition/). – Right now [Matrix federation is being introduced](https://www.process-one.net/blog/matrix-protocol-added-to-ejabberd/) to allow interop between ejabberd and Matrix servers, to [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/#getejabberd) internally or on [Fluux](https://fluux.io/?ref=process-one.net) ejabberd SaaS platform. It will come later to ejabberd Community Server. ejabberd keeps on improving at a steady pace and is happy to open to other protocols and communities. ## Some source code statistics The oldest unchanged function in ejabberd is probably one of the least used: [stop/0](https://github.com/processone/ejabberd/blob/master/src/ejabberd.erl?ref=process-one.net#L51). And the oldest functional line is the [SETS macro definition](https://github.com/processone/ejabberd/blob/master/src/ejabberd%5Fc2s.erl?ref=process-one.net#L59). The ejabberd repository got 1,070,325 line insertions and 901,287 line deletions. When counting both ejabberd and the dependency libraries, they got 1.693.180 line insertions and 1.108.873 line deletions. With all this, the ejabberd source code went from 13 files to 868, from 1,448 lines of code to 480,961. Looking at the programming languages of ejabberd and its libraries, Erlang is obviously the major one, and C comes as a relevant second: | Language | Files | Lines | Code | Comments | Blanks | | ------------ | ----- | ------ | ------ | -------- | ------ | | ABNF | 3 | 128 | 110 | 3 | 15 | | ASN.1 | 1 | 14 | 10 | 0 | 4 | | Autoconf | 14 | 696 | 544 | 33 | 119 | | Batch | 4 | 31 | 21 | 0 | 10 | | **C** | 20 | 187549 | 139764 | 39614 | 8171 | | C Header | 8 | 11199 | 3783 | 6979 | 437 | | C++ | 1 | 533 | 442 | 17 | 74 | | CSS | 5 | 532 | 507 | 0 | 25 | | Elixir | 32 | 1888 | 1469 | 130 | 289 | | **Erlang** | 604 | 247901 | 208912 | 18368 | 20621 | | JavaScript | 2 | 23 | 21 | 1 | 1 | | Lua | 1 | 16 | 16 | 0 | 0 | | Makefile | 21 | 848 | 635 | 10 | 203 | | Perl | 3 | 1086 | 897 | 63 | 126 | | Python | 1 | 53 | 49 | 0 | 4 | | RPM Specfile | 3 | 5408 | 3928 | 1059 | 421 | | Shell | 21 | 4031 | 3263 | 336 | 432 | | SQL | 9 | 3857 | 2994 | 303 | 560 | | TCL | 3 | 1179 | 1002 | 69 | 108 | | Plain Text | 13 | 1870 | 0 | 1561 | 309 | | YAML | 20 | 1448 | 1357 | 53 | 38 | ### ejabberd 22.10 URL: https://www.process-one.net/blog/ejabberd-22-10/ Last updated: 2024-09-16T12:37:52.000Z This version brings support for latest [MIX](https://xmpp.org/extensions/xep-0369.html?ref=process-one.net) protocol version, and significantly improves detection and recovery of SQL connection issues. There are no breaking changes in SQL schemas, configuration, or commands API. If you develop an ejabberd module, notice two hooks have changed: `muc_subscribed` and `muc_unsubscribed`. A more detailed explanation of those topics and other features: ## Erlang/OTP 19.3 You may remember than in the previous ejabberd release, [ejabberd 22.05](https://www.process-one.net/blog/ejabberd-22-05/), support for [Erlang/OTP](https://www.erlang.org/?ref=process-one.net) 25 was introduced, even if 24.3 is still recommended for stable deployments. It is expected that around April 2023, GitHub Actions will remove Ubuntu 18 and it will not be possible to run automatic tests for ejabberd using Erlang 19.3, the lowest possible will be Erlang 20.0. For that reason, the planned schedule is: - **ejabberd 22.10** - Usage of Erlang 19.3 is **discouraged** - Anybody still using Erlang 19.3 is encouraged to upgrade to 24.3, or at least 20.0 - **ejabberd 23.05 (or later)** - Support for Erlang 19.3 is **deprecated** - Erlang requirement softly increased in `configure.ac` - Announce: no warranty ejabberd can compile, start or pass the Common Tests suite using Erlang 19.3 - Provide instructions for anybody to manually re-enable it and run the tests - **ejabberd 23.xx+1 (or later)** - Support for Erlang 19.3 is **removed** completely in the source code ## New `log_burst_limit_*` options Two options were added in [#3865](https://github.com/processone/ejabberd/issues/3865?ref=process-one.net) to configure logging limits in case of high traffic: - `log_burst_limit_window_time` defines the time period to rate-limit log messages by. - `log_burst_limit_count` defines the number of messages to accept in that time period before starting to drop them. ## Support `ERL_DIST_PORT` option to work without epmd The option `ERL_DIST_PORT` is added to `ejabberdctl.cfg`, disabled by default. When this option is set to a port number, the Erlang node will not start [epmd](https://docs.ejabberd.im/admin/guide/security/?ref=process-one.net#epmd) and will not listen in a range of ports for erlang connections (typically used for [ejabberdctl](https://docs.ejabberd.im/admin/guide/managing/?ref=process-one.net#ejabberdctl) and for [clustering](https://docs.ejabberd.im/admin/guide/clustering/?ref=process-one.net#clustering-setup)). Instead, the erlang node will simply listen in the configured port number. Please note: - Erlang/OTP 23.1 or higher is required to use `ERL_DIST_PORT` - `make relive` doesn’t support `ERL_DIST_PORT`, neither rebar3 nor elixir - To start several ejabberd nodes in the same machine, configure a different port in each node ## Support version macros in `captcha_cmd` option Support for the `@VERSION@` and `@SEMVER@` macros was added to the `captcha_cmd` option in [#3835](https://github.com/processone/ejabberd/issues/3835?ref=process-one.net). Those macros are useful because the example captcha scripts are copied in a path like `ejabberd-VERSION/priv/bin` that depends on the ejabberd version number and changes for each release. Also, depending on the install method (rebar3 or Elixir’s mix), that `VERSION` may be in `XX.YY` or in `SEMVER` format (respectively). Now, it’s possible to configure like this: ```yaml captcha_cmd: /opt/ejabberd-@VERSION@/lib/ejabberd-@SEMVER@/priv/bin/captcha.sh ``` ## Hook Changes Two hooks have changed: `muc_subscribed` and `muc_unsubscribed`. Now they get the packet and room state, and can modify the sent packets. If you write source code that adds functions to those hooks, please notice that previously they were ran like: ```erlang ejabberd_hooks:run(muc_subscribed, ServerHost, [ServerHost, Room, Host, BareJID]); ``` and now they are ran like this: ```erlang {Packet2a, Packet2b} = ejabberd_hooks:run_fold(muc_subscribed, ServerHost, {Packet1a, Packet1b}, [ServerHost, Room, Host, BareJID, StateData]), ``` being Packet1b a copy of Packet1a without the `jid` attribute in the `muc_subscribe` element. ## Translations Updates Several translations were improved: Ukrainian, Chinese (Simplified), French, German, Russian, Portuguese (Brazil), Spanish and Catalan. Thanks to all this people that contribute in [ejabberd at Weblate](https://hosted.weblate.org/projects/ejabberd/ejabberd-po/?ref=process-one.net)! ## WebAdmin page for external modules A new page is added in ejabberd’s WebAdmin to view available external modules, update their source code, install, upgrade and remove them. All this is equivalent to what was already available using API commands from the [modules tag](https://docs.ejabberd.im/developer/ejabberd-api/admin-tags/?ref=process-one.net#modules). Many modules in the [ejabberd-contrib](https://github.com/processone/ejabberd-contrib?ref=process-one.net) git repository have been improved, and their documentation updated. Additionally, those modules are now automatically tested, at least compilation, installation and static code analysis. ## Documentation Improvements In addition to the normal improvements and fixes, two sections in the [ejabberd Documentation](https://docs.ejabberd.im/?ref=process-one.net) are greatly improved: - [ejabberd for Elixir Developers](https://docs.ejabberd.im/developer/extending-ejabberd/elixir/?ref=process-one.net) - [Getting Started with MIX](https://docs.ejabberd.im/tutorials/mix-010/?ref=process-one.net) ## ChangeLog ### General - Add `log_burst_limit_*` options ([#3865](https://github.com/processone/ejabberd/issues/3865?ref=process-one.net)) - Support `ERL_DIST_PORT` option to work without epmd - Auth JWT: Catch all errors from `jose_jwt:verify` and log debugging details ([#3890](https://github.com/processone/ejabberd/issues/3890?ref=process-one.net)) - CAPTCHA: Support `@VERSION@` and `@SEMVER@` in `captcha_cmd` option ([#3835](https://github.com/processone/ejabberd/issues/3835?ref=process-one.net)) - HTTP: Fix unix socket support ([#3894](https://github.com/processone/ejabberd/issues/3894?ref=process-one.net)) - HTTP: Handle invalid values in `X-Forwarded-For` header more gracefuly - Listeners: Let module take over socket - Listeners: Don’t register listeners that failed to start in config reload - `mod_admin_extra`: Handle empty roster group names - `mod_conversejs`: Fix crash when mod\_register not enabled ([#3824](https://github.com/processone/ejabberd/issues/3824?ref=process-one.net)) - `mod_host_meta`: Complain at start if listener is not encrypted - `mod_ping`: Fix regression on `stop_ping` in clustering context ([#3817](https://github.com/processone/ejabberd/issues/3817?ref=process-one.net)) - `mod_pubsub`: Don’t crash on command failures - `mod_shared_roster`: Fix cache invalidation - `mod_shared_roster_ldap`: Update roster\_get hook to use `#roster_item{}` - `prosody2ejabberd`: Fix parsing of scram password from prosody ### MIX - Fix MIX’s filter\_nodes - Return user jid on join - `mod_mix_pam`: Add new MIX namespaces to disco features - `mod_mix_pam`: Add handling of IQs with newer MIX namespaces - `mod_mix_pam`: Do roster pushes on join/leave - `mod_mix_pam`: Parse sub elements of the mix join remote result - `mod_mix_pam`: Provide MIX channels as roster entries via hook - `mod_mix_pam`: Display joined channels on webadmin page - `mod_mix_pam`: Adapt to renaming of `participant-id` from mix\_roster\_channel record - `mod_roster`: Change hook type from `#roster{}` to `#roster_item{}` - `mod_roster`: Respect MIX “ setting - `mod_roster`: Adapt to change of mix\_annotate type to boolean in roster\_query - `mod_shared_roster`: Fix wrong hook type `#roster{}` (now `#roster_item{}`) ### MUC: - Store role, and use it when joining a moderated room ([#3330](https://github.com/processone/ejabberd/issues/3330?ref=process-one.net)) - Don’t persist `none` role ([#3330](https://github.com/processone/ejabberd/issues/3330?ref=process-one.net)) - Allow MUC service admins to bypass max\_user\_conferences limitation - Show allow\_query\_users room option in disco info ([#3830](https://github.com/processone/ejabberd/issues/3830?ref=process-one.net)) - Don’t set affiliation to `none` if it’s already `none` in `mod_muc_room:process_item_change/3` - Fix mucsub unsubscribe notification payload to have muc\_unsubcribe in it - Allow muc\_{un}subscribe hooks to modify sent packets - Pass room state to muc\_{un}subscribed hook - The archive\_msg export fun requires MUC Service for room archives - Export `mod_muc_admin:get_room_pid/2` - Export function for getting room diagnostics ### SQL - Handle errors reported from begin/commit inside transaction - Make connection close errors bubble up from inside sql transaction - Make first sql reconnect wait shorter time - React to sql driver process exit earlier - Skip connection exit message when we triggered reconnection - Add syntax\_tools to applications, required when using ejabberd\_sql\_pt ([#3869](https://github.com/processone/ejabberd/issues/3869?ref=process-one.net)) - Fix mam delete\_old\_messages\_batch for sql backend - Use `INSERT ... ON DUPLICATE KEY UPDATE` for upsert on mysql - Update mysql library - Catch mysql connection being close earlier ### Compile - `make all`: Generate start scripts here, not in `make install` ([#3821](https://github.com/processone/ejabberd/issues/3821?ref=process-one.net)) - `make clean`: Improve this and “distclean” - `make deps`: Ensure deps configuration is ran when getting deps ([#3823](https://github.com/processone/ejabberd/issues/3823?ref=process-one.net)) - `make help`: Update with recent changes - `make install`: Don’t leak DESTDIR in files copied by ‘make install’ - `make options`: Fix error reporting on OTP24+ - `make update`: configure also in this case, similarly to `make deps` - Add definition to detect OTP older than 25, used by ejabberd\_auth\_http - Configure eimp with mix to detect image convert properly ([#3823](https://github.com/processone/ejabberd/issues/3823?ref=process-one.net)) - Remove unused macro definitions detected by rebar3\_hank - Remove unused header files which content is already in xmpp library ### Container - Get ejabberd-contrib sources to include them - Copy `.ejabberd-modules` directory if available - Do not clone repo inside container build - Use `make deps`, which performs additional steps ([#3823](https://github.com/processone/ejabberd/issues/3823?ref=process-one.net)) - Support `ERL_DIST_PORT` option to work without epmd - Copy `ejabberd-docker-install.bat` from docker-ejabberd git and rename it - Set a less frequent healthcheck to reduce CPU usage ([#3826](https://github.com/processone/ejabberd/issues/3826?ref=process-one.net)) - Fix build instructions, add more podman examples ### Installers - make-binaries: Include CAPTCHA script with release - make-binaries: Edit rebar.config more carefully - make-binaries: Fix linking of EIMP dependencies - make-binaries: Fix GitHub release version checks - make-binaries: Adjust Mnesia spool directory path - make-binaries: Bump Erlang/OTP version to 24.3.4.5 - make-binaries: Bump Expat and libpng versions - make-packages: Include systemd unit with RPM - make-packages: Fix permissions on RPM systems - make-installers: Support non-root installation - make-installers: Override code on upgrade - make-installers: Apply cosmetic changes ### External modules - ext\_mod: Support managing remote nodes in the cluster - ext\_mod: Handle correctly when COMMIT.json not found - Don’t bother with COMMIT.json user-friendly feature in automated user case - Handle not found COMMIT.json, for example in GH Actions - Add WebAdmin page for managing external modules ### Workflows Actions - Update workflows to Erlang 25 - Update workflows: Ubuntu 18 is deprecated and 22 is added - CI: Remove syntax\_tools from applications, as fast\_xml fails Dialyzer - Runtime: Add Xref options to be as strict as CI ### Full Changelog [https://github.com/processone/ejabberd/compare/22.05…22.10](https://github.com/processone/ejabberd/compare/22.05...22.10?ref=process-one.net) ## ejabberd 22.10 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are available in [ejabberd Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). For convenience, there are alternative download locations like the [ejabberd DEB/RPM Packages Repository](https://repo.process-one.net/?ref=process-one.net) and the [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The Docker image is in [Docker Hub](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net), and there’s an alternative Container image in [GitHub Packages](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you suspect that you’ve found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Matrix protocol added to ejabberd URL: https://www.process-one.net/blog/matrix-protocol-added-to-ejabberd/ Last updated: 2024-09-16T12:40:03.000Z ejabberd is already the most versatile and scalable messaging server. In this post, we are giving a sneak peak at what is coming next. ejabberd just get new ace in it sleeve – you can now use ejabberd to talk with other Matrix servers, a protocol sometimes used for small corporate server messaging. Of course, you all know ejabberd supports the XMPP instant messaging protocol with hundreds of XMPP extensions, this is what it is famous for. The second major protocol in ejabberd is MQTT. ejabberd support MQTT 5 with clustering, and is massively scalable. ejabberd can be used to implement Internet of Things projects, using either XMPP or MQTT and it also supports hybrid workflow, where you can mix humans and machines exchanging messages on the same platform. It also supports SIP, as you can connect to ejabberd with a SIP client, so that you can use a softphone directly with ejabberd for internal calls. So far, so good, ejabberd leading both in terms of performance and number of messaging protocol it supports. We always keep an eye on new messaging protocol. Recently, the Matrix protocol emerged as a new way to implement messaging for the small corporate servers. Of course, by design, the Matrix protocol cannot scale as well as XMPP or MQTT protocols. At the heart of Matrix protocol, you have a kind of merging algorithm that reminds a bit of Google Wave. It means that a conversation is conceptually represented as a sort document you constantly merge on the server. This is a consuming process that is happening on the server for each message received in all conversations. That’s why Matrix has the reputation to be so difficult to scale. Even if it is not as scalable as XMPP, we believe that we can make Matrix much more scalable than what it is now. That’s what we are doing right now. As a first step, we have been working on implementing a large subset of the Matrix protocol as a bridge in ejabberd. It means that an ejabberd server will be able to act as a Matrix server in the Matrix ecosystem. XMPP users will be able to exchange messages with Matrix users, transparently. To do that, we implemented the Matrix protocol for conversations and the server-to-server protocol to allow interop between XMPP and Matrix protocol. This feature coming first for our customers, in the coming weeks, whether they are using [ejabberd Business Edition](https://www.process-one.net/en/ejabberd/#getejabberd) internally or on [Fluux](https://fluux.io/?ref=process-one.net) ejabberd SaaS platform. It will come later to ejabberd Community Edition. ### Announcing ejabberd DEB and RPM Repositories URL: https://www.process-one.net/blog/announcing-ejabberd-deb-and-rpm-repositories/ Last updated: 2026-03-19T15:01:48.000Z All details on how to set this up are described on the dedicated website: [https://repo.process-one.net](https://repo.process-one.net/?ref=process-one.net) ![ejabberd installation log](https://www.process-one.net/wp-content/uploads/2022/06/ejabberd.png) # What packages are available? Currently, the latest DEB and RPM packages are available for the open-source ejabberd version (eCS 22.05). New versions will be published as they’re released to [https://repo.process-one.net](https://repo.process-one.net/?ref=process-one.net). # Which platforms are currently supported? The DEB and RPM packages currently target popular `amd64` and `arm64` systems. So if you are using Debian or centOS you should be fine. If your platform is not in this list, you can [open an issue on Github](https://github.com/processone/ejabberd/issues/?ref=process-one.net) describing which platform you would like to be added. We aim to expand the support to other widely adopted architectures and platforms in the future. # What is next? In addition to providing packages for ejabberd for upcoming releases, as well as expanding distribution and architecture support, we will make improvements to this official repository. Away from prying eyes, we’ve been studying the possibility to make ejabberd’s installers (.deb, .rpm, .run) directly on Github below each *Release* and that’s now the case! You can check them [here](https://github.com/processone/ejabberd/releases?ref=process-one.net) now. We’re looking forward to the community feedback on these packages to provide the best possible experience. Feel free to get in touch if needed! ### ejabberd 22.05 URL: https://www.process-one.net/blog/ejabberd-22-05/ Last updated: 2024-09-16T13:42:15.000Z – Improved MQTT, MUC, and ConverseJS integration – New installers and container – Support Erlang/OTP 25 When upgrading from the previous version please notice: there are minor changes in SQL schemas, the included rebar and rebar3 binaries require Erlang/OTP 22 or higher, and `make rel` uses different paths. There are no breaking changes in configuration, and only one change in commands API. A more detailed explanation of those topics and other features: ## New Indexes in SQL for MUC Two new indexes were added to optimize MUC. Those indexes can be added in the database before upgrading to 22.05, that will not affect older versions. To update an existing database, depending on the schema used to create it: - MySQL (`mysql.sql` or `mysql.new.sql`): ```sql CREATE INDEX i_muc_room_host_created_at ON muc_room(host(75), created_at); CREATE INDEX i_muc_room_subscribers_jid USING BTREE ON muc_room_subscribers(jid); ``` - PostgreSQL (`pg.sql` or `pg.new.sql`): ```sql CREATE INDEX i_muc_room_host_created_at ON muc_room USING btree (host, created_at); CREATE INDEX i_muc_room_subscribers_jid ON muc_room_subscribers USING btree (jid); ``` - SQLite (`lite.sql` or `lite.new.sql`): ```sql CREATE INDEX i_muc_room_host_created_at ON muc_room (host, created_at); CREATE INDEX i_muc_room_subscribers_jid ON muc_room_subscribers(jid); ``` - MS SQL (`mssql.sql`): ```sql CREATE INDEX [muc_room_host_created_at] ON [muc_registered] (host, nick) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON); CREATE INDEX [muc_room_subscribers_jid] ON [muc_room_subscribers] (jid); ``` ## Fixes in PostgreSQL New Schema If you moved your PostgreSQL database from old to new schema using [mod\_admin\_update\_sql](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod-admin-update-sql) or the [update\_sql](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#update-sql) API command, be aware that those methods forgot to perform some updates. To fix an existing PostgreSQL database schema, apply those changes manually: ```sql ALTER TABLE archive DROP CONSTRAINT i_archive_sh_peer; ALTER TABLE archive DROP CONSTRAINT i_archive_sh_bare_peer; CREATE INDEX i_archive_sh_username_peer ON archive USING btree (server_host, username, peer); CREATE INDEX i_archive_sh_username_bare_peer ON archive USING btree (server_host, username, bare_peer); DROP TABLE carboncopy; ALTER TABLE push_session DROP CONSTRAINT i_push_session_susn; CREATE UNIQUE INDEX i_push_session_susn ON push_session USING btree (server_host, username, service, node); ALTER TABLE mix_pam DROP CONSTRAINT i_mix_pam; ALTER TABLE mix_pam DROP CONSTRAINT i_mix_pam_us; CREATE UNIQUE INDEX i_mix_pam ON mix_pam (username, server_host, channel, service); CREATE INDEX i_mix_pam_us ON mix_pam (username, server_host); ALTER TABLE route DROP CONSTRAINT i_route; CREATE UNIQUE INDEX i_route ON route USING btree (domain, server_host, node, pid); ALTER TABLE mqtt_pub DROP CONSTRAINT i_mqtt_topic; CREATE UNIQUE INDEX i_mqtt_topic_server ON mqtt_pub (topic, server_host); ``` ## API Changes The `oauth_revoke_token` API command has changed its returned result. Check [oauth\_revoke\_token](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#oauth-revoke-token) documentation. ## API Batch Alternatives If you use the command [delete\_old\_messages](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#delete-old-messages) periodically and noticed it can bring your system to an undesirable state with high CPU and memory consumption… Now you can use [delete\_old\_messages\_batch](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#delete-old-messages-batch), which performs the operation in batches, by setting the number of messages to delete per batch and the desired rate of messages to delete per minute. Two companion commands are added: [delete\_old\_messages\_status](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#delete-old-messages-status) to check the status of the batch operation, and [abort\_delete\_old\_messages](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#abort-delete-old-messages) to abort the batch process. There are also new equivalent commands to delete old MAM messages. ## Erlang/OTP and Elixir From now, [Erlang/OTP](https://www.erlang.org/?ref=process-one.net) 25 is supported. As that’s a brand new version, for stable deployments you may prefer to use 24.3 or other lower version. Notice that ejabberd can be compiled with Erlang as old as 19.3, but the rebar and rebar3 binaries included with ejabberd 22.05 require at least Erlang 22\. This means that, to compile ejabberd 22.05 with those tools using an Erlang version between 19.3 and 21.3, you should get yourself a compatible rebar/rebar3 binary. If your operating system doesn’t provide a suitable one, you can download the old ones: [rebar from ejabberd 21.12](https://github.com/processone/ejabberd/raw/21.12/rebar?ref=process-one.net) and [rebar3 from ejabberd 21.12](https://github.com/processone/ejabberd/raw/21.12/rebar3?ref=process-one.net). Regarding [Elixir](https://elixir-lang.org/?ref=process-one.net) supported versions: - Elixir 1.4 or higher is supported for compilation, but: - Elixir 1.10 is required to build OTP releases (`make rel` and `make dev`) - Elixir 1.11 is required to run `make relive` - Elixir lower than 1.11.4 requires Erlang lower than 24 to build OTP releases ## mod\_conversejs `mod_conversejs` was introduced in [ejabberd 21.12](https://www.process-one.net/blog/ejabberd-21-12/) to serve a simple page for the [Converse.js](https://conversejs.org/?ref=process-one.net) XMPP web browser client. Several improvements in `mod_conversejs` now allow a simpler configuration, and more customization at the same time: - The options now support the `@HOST@` keyword - The options now support `auto`, which uses local or remote Converse files - The Converse’s `auth` and `register` options are set based on ejabberd’s configuration - `default_domain` option now has `@HOST@` as default value, not the first defined vhost - `conversejs_options`: New option to setup additional options for Converse - `conversejs_resources`: New option to serve converse.js files (no need to setup an additional web server) For example, if you downloaded Converse, now you can setup WebSocket, `mod_conversejs`, and serve Converse without additional web server, in an encrypted port, as simple as: ```yaml listen: - port: 443 module: ejabberd_http tls: true request_handlers: /websocket: ejabberd_http_ws /conversejs: mod_conversejs modules: mod_conversejs: conversejs_resources: "/home/ejabberd/conversejs-9.0.0/package/dist" ``` With that configuration, Converse is available in https://localhost/conversejs More details in the [mod\_conversejs documentation](https://docs.ejabberd.im/admin/configuration/modules/?ref=process-one.net#mod-conversejs). ## New Installers For many years, the release of a new ejabberd source code package was accompanied with binary installers, built using InstallBuilder and CEAN, and available in the [ProcessOne Downloads](https://www.process-one.net/en/ejabberd/downloads/) page. Since this ejabberd 22.05, there are new installers that use a completely different build method: - they are built using the tools provided in [PR 3781](https://github.com/processone/ejabberd/pull/3781?ref=process-one.net) - they use the most recent stable dependencies - they are available for `linux/amd64` and `linux/arm64` architectures - they are built automatically using the [Installers Workflow](https://github.com/processone/ejabberd/blob/master/.github/workflows/installers.yml?ref=process-one.net) - for stable releases, they are available for download in the [ejabberd GitHub Releases](https://github.com/processone/ejabberd/releases?ref=process-one.net) - they are built also for every commit in `master` branch, and available for download in the [results of Installers Workflow](https://github.com/processone/ejabberd/actions/workflows/installers.yml?ref=process-one.net) - if the installer is ran by root, it installs in `/opt/ejabberd*` and setups systemd service - if ran by a regular user, it asks installation path However, compared to the old installers, those new installers: - do not ask for domain: now you must edit `ejabberd.yml` and set the `hosts` option - do not register the first Jabber account and grant admin rights: you must do it yourself Please give those new installers a try, and comment any problem, improvement or ideas. ## New Container Image In addition to the `ejabberd/ecs` Docker container image published in [Docker Hub](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net), there is a new container image published in [ejabberd GitHub Packages](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). Its usage is similar to the `ejabberd/ecs` image, with some benefits and changes worth noting: - it’s available for `linux/amd64` and `linux/arm64` architectures - it’s built also for `master` branch, in addition to the stable ejabberd releases - it includes less customizations to the base ejabberd compared to `ejabberd/ecs` - it stores data in `/opt/ejabberd/` instead of `/home/ejabberd/` See its documentation in [CONTAINER](https://github.com/processone/ejabberd/blob/master/CONTAINER.md?ref=process-one.net). If you used previous images from that GitHub Packages registry please note: until now they were identical to the ones in Docker Hub, but the new 22.05 image is slightly different: it stores data in `/opt/ejabberd/` instead of `/home/ejabberd/`. You can update the paths to the container volumes in this new image, or switch to Docker Hub to continue using the old same images. ## Source Code Package Until now, the source code package available in the [ProcessOne Downloads](https://www.process-one.net/en/ejabberd/downloads/) page was prepared manually together with the binary installers. Now all this is automated in GitHub, and the new source code package is simply the same one available in [GitHub Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). The differences are: - instead of `tgz` it’s now named `tar.gz` - it contains the `.gitignore` file - it lacks the `configure` and `aclocal.m4` files The compilation instructions are slightly improved and moved to a separate file: [COMPILE.md](https://github.com/processone/ejabberd/blob/master/COMPILE.md?ref=process-one.net) ## New `make relive` This new `make relive` is similar to `ejabberdctl live`, but without requiring to install or build an OTP release: compile and start ejabberd immediately! Quickly put: - Prepare it with: `./autogen.sh && ./configure --with-rebar=./rebar3 && make` - Or use this if you installed Elixir: `./autogen.sh && ./configure --with-rebar=mix && make` - Start without installing (it recompiles when necessary): `make relive` - It stores config, database and logs in `_build/relive/` - There you can find the well-known script: `_build/relive/ejabberdctl` - In that erlang shell, recompile source code and reload at runtime: `ejabberd_admin:update().` Please note, when `make relive` uses Elixir’s Mix instead of Rebar3, it requires Elixir 1.11.0 or higher. ## New GitHub Workflows As you may notice while reading these release notes, there are new github workflows to build and publish the new installers and the container images, in addition to the Common Tests suite. The last added workflow is Runtime. The Runtime workflow ensures that ejabberd compiles with Erlang/OTP 19.3 up to 25, using rebar, rebar3 and several Elixir versions. It also checks an OTP release can be built, started, register an account, and stop ejabberd. See its source code [runtime.yml](https://github.com/processone/ejabberd/blob/master/.github/workflows/runtime.yml?ref=process-one.net) and [its results](https://github.com/processone/ejabberd/actions/workflows/runtime.yml?ref=process-one.net). If you have troubles compiling ejabberd, check if those results reproduce your problem, and also see the steps used to compile and start ejabberd using Ubuntu. ## Translations Updates The German, Portuguese, Portuguese (Brazil), Spanish and Catalan translations are updated and completed. The French translation was greatly improved and updated too. ## Documentation Improvements Some sections in the [ejabberd Documentation](https://docs.ejabberd.im/?ref=process-one.net) are improved: - [MQTT Support](https://docs.ejabberd.im/admin/guide/mqtt/?ref=process-one.net) - [OAuth Support](https://docs.ejabberd.im/developer/ejabberd-api/oauth/?ref=process-one.net) - [Reload Config at Runtime](https://docs.ejabberd.im/admin/configuration/file-format/?ref=process-one.net#reload-at-runtime) - [Update Modules at Runtime](https://docs.ejabberd.im/admin/upgrade/?ref=process-one.net#module-update-process) ## ChangeLog ### Core - C2S: Don’t expect that socket will be available in `c2s_terminated` hook - Event handling process hook tracing - Guard against `erlang:system_info(logical_processors)` not always returning a number - `domain_balancing`: Allow for specifying `type` only, without specifying `component_number` ### MQTT - Add TLS certificate authentication for MQTT connections - Fix login when generating client id, keep connection record ([#3593](https://github.com/processone/ejabberd/issues/3593?ref=process-one.net)) - Pass property name as expected in `mqtt_codec` (fixes login using MQTT 5) - Support MQTT subscriptions spread over the cluster ([#3750](https://github.com/processone/ejabberd/issues/3750?ref=process-one.net)) ### MUC - Attach meta field with real jid to mucsub subscription events - Handle user removal - Stop empty MUC rooms 30 seconds after creation - `default_room_options`: Update options configurable - `subscribe_room_many_max_users`: New option in `mod_muc_admin` ### `mod_conversejs` - Improved options to support `@HOST@` and `auto` values - Set `auth` and `register` options based on ejabberd configuration - `conversejs_options`: New option - `conversejs_resources`: New option ### PubSub - `mod_pubsub`: Allow for limiting `item_expire` value - `mod_pubsub`: Unsubscribe JID on whitelist removal - `node_pep`: Add config-node and multi-items features ([#3714](https://github.com/processone/ejabberd/issues/3714?ref=process-one.net)) ### SQL - Improve compatibility with various db engine versions - Sync old-to-new schema script with reality ([#3790](https://github.com/processone/ejabberd/issues/3790?ref=process-one.net)) - Slight improvement in MSSQL testing support, but not yet complete ### Other Modules - `auth_jwt`: Checking if an user is active in SM for a JWT authenticated user ([#3795](https://github.com/processone/ejabberd/issues/3795?ref=process-one.net)) - `mod_configure`: Implement Get List of Registered/Online Users from XEP-0133 - `mod_host_meta`: New module to serve host-meta files, see XEP-0156 - `mod_mam`: Store all mucsub notifications not only message notifications - `mod_ping`: Delete ping timer if resource is gone after the ping has been sent - `mod_ping`: Don’t send ping if resource is gone - `mod_push`: Fix notifications for pending sessions (XEP-0198) - `mod_push`: Keep push session ID on session resume - `mod_shared_roster`: Adjust special group cache size - `mod_shared_roster`: Normalize JID on unset\_presence ([#3752](https://github.com/processone/ejabberd/issues/3752?ref=process-one.net)) - `mod_stun_disco`: Fix parsing of IPv6 listeners ### Dependencies - autoconf: Supported from 2.59 to the new 2.71 - fast\_tls: Update to 1.1.14 to support OpenSSL 3 - jiffy: Update to 1.1.1 to support Erlang/OTP 25.0-rc1 - luerl: Update to 1.0.0, now available in hex.pm - lager: This dependency is used only when Erlang is older than 22 - rebar2: Updated binary to work from Erlang/OTP 22 to 25 - rebar3: Updated binary to work from Erlang/OTP 22 to 25 - `make update`: Fix when used with rebar 3.18 ### Compile - `mix release`: Copy `include/` files for ejabberd, deps and otp, in `mix.exs` - `rebar3 release`: Fix ERTS path in `ejabberdctl` - `configure.ac`: Set default ejabberd version number when not using git - `mix.exs`: Move some dependencies as optional - `mix.exs`: No need to use Distillery, Elixir has built-in support for OTP releases ([#3788](https://github.com/processone/ejabberd/issues/3788?ref=process-one.net)) - `tools/make-binaries`: New script for building Linux binaries - `tools/make-installers`: New script for building command line installers ### Start - New `make relive` similar to `ejabberdctl live` without installing - `ejabberdctl`: Fix some warnings detected by ShellCheck - `ejabberdctl`: Mention in the help: `etop`, `ping` and `started`/`stopped` - `make rel`: Switch to paths: `conf/`, `database/`, `logs/` - `mix.exs`: Add `-boot` and `-boot_var` in `ejabberdctl` instead of adding `vm.args` - `tools/captcha.sh`: Fix some warnings detected by ShellCheck ### Commands - Accept more types of ejabberdctl commands arguments as JSON-encoded - `delete_old_mam_messages_batch`: New command with rate limit - `delete_old_messages_batch`: New command with rate limit - `get_room_occupants_number`: Don’t request the whole MUC room state ([#3684](https://github.com/processone/ejabberd/issues/3684?ref=process-one.net), [#1964](https://github.com/processone/ejabberd/issues/1964?ref=process-one.net)) - `get_vcard`: Add support for MUC room vCard - `oauth_revoke_token`: Add support to work with all backends - `room_unused_*`: Optimize commands in SQL by reusing `created_at` - `rooms_unused_...`: Let `get_all_rooms` handle `global` argument ([#3726](https://github.com/processone/ejabberd/issues/3726?ref=process-one.net)) - `stop|restart`: Terminate ejabberd\_sm before everything else to ensure sessions closing ([#3641](https://github.com/processone/ejabberd/issues/3641?ref=process-one.net)) - `subscribe_room_many`: New command ### Translations - Updated Catalan - Updated French - Updated German - Updated Portuguese - Updated Portuguese (Brazil) - Updated Spanish ### Workflows - CI: Publish CT logs and Cover on failure to an external GH Pages repo - CI: Test shell scripts using ShellCheck ([#3738](https://github.com/processone/ejabberd/issues/3738?ref=process-one.net)) - Container: New workflow to build and publish containers - Installers: Add job to create draft release - Installers: New workflow to build binary packages - Runtime: New workflow to test compilation, rel, starting and ejabberdctl ### Full Changelog [All changes between 21.12 and 22.05](https://github.com/processone/ejabberd/compare/21.12...22.05?ref=process-one.net) ## ejabberd 22.05 download & feedback As usual, the release is tagged in the Git source code repository on [GitHub](https://github.com/processone/ejabberd?ref=process-one.net). The source package and installers are now available in [GitHub Release / Tags](https://github.com/processone/ejabberd/tags?ref=process-one.net). To check the `*.asc` signature files, see [How to verify ProcessOne downloads integrity](https://www.process-one.net/blog/verifying%5Fprocess%5Fone%5Fdownloads%5Fintegrity/). The Docker image is in [Docker Hub](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net), and a new Container image at [GitHub Packages](https://github.com/processone/ejabberd/pkgs/container/ejabberd?ref=process-one.net). If you suspect that you’ve found a bug, please search or fill a bug report on [GitHub Issues](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### ejabberd 21.12 URL: https://www.process-one.net/blog/ejabberd-21-12/ Last updated: 2024-09-16T13:44:41.000Z When upgrading from previous versions, please notice: there’s a change in `mod_register_web` behaviour, and PosgreSQL database, please take a look if they affect your installation. A more detailed explanation of those topics: ### Optimized MucSub and Multicast processing More efficient processing of [MucSub](https://docs.ejabberd.im/developer/xmpp-clients-bots/extensions/muc-sub/?ref=process-one.net) and Multicast ([XEP-0033](https://xmpp.org/extensions/xep-0033.html?ref=process-one.net)) messages addressed to big number of addresses. ### Support MUC Hats MUC Hats ([XEP-0317](https://xmpp.org/extensions/xep-0317.html?ref=process-one.net)) defines a more extensible model for roles and affiliations in Multi-User Chat rooms. This protocol was deferred, but it is supported by several clients and servers. ejabberd’s implementation supports both the XEP schema, and also the Conversejs/Prosody custom schema. ### New `mod_conversejs` This module serves a simple page to allow the [Converse.js](https://conversejs.org/?ref=process-one.net) XMPP web browser client connect to ejabberd. It can use ejabberd’s Websockets or BOSH (HTTP-Bind). By default this module points to the public online client available at converse.js. Alternatively, you can download the client and host it locally with a configuration like this: ```yaml hosts: - localhost listen: - port: 5280 ip: "::" module: ejabberd_http tls: false request_handlers: /websocket: ejabberd_http_ws /conversejs: mod_conversejs /conversejs_files: mod_http_fileserver modules: mod_conversejs: websocket_url: "ws://localhost:5280/websocket" conversejs_script: "http://localhost:5280/conversejs_files/converse.min.js" conversejs_css: "http://localhost:5280/conversejs_files/converse.min.css" mod_http_fileserver: docroot: "/home/ejabberd/conversejs-9.0.0/package/dist" accesslog: "/var/log/ejabberd/fileserver-access.log" ``` ### Many PubSub improvements Add `delete_old_pubsub_items` command. Add a command for keeping only the specified number of items on each node and removing all older items. This might be especially useful if nodes may be configured to have no ‘max\_items’ limit. Add `delete_expired_pubsub_items` command Support XEP-0060’s pubsub#item\_expire feature by adding a command for deleting expired PubSub items. Fix `get_max_items_node/1` specification Make it explicit that the get\_max\_items\_node/1 function returns ?MAXITEMS if the ‘max\_items\_node’ option isn’t specified. The function didn’t actually fall back to ‘undefined’ (but to the ‘max\_items\_node’ default; i.e., ?MAXITEMS) anyway. This change just clarifies the behavior and adjusts the function specification accordingly. ### Improvements in the ejabberd Documentation web Added many cross-links between modules, options, and specific sections. Added a new [API Tags](https://docs.ejabberd.im/developer/ejabberd-api/admin-tags/?ref=process-one.net) page similar to “ejabberdctl help tags”. Improved the [API Reference](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net) page, so commands show the tags and the definer module. ### Configuration changes `mod_register_web` is now affected by the restrictions that you configure in `mod_register` ([#3688](https://github.com/processone/ejabberd/issues/3688?ref=process-one.net)). `mod_register` gets a new option, `allow_modules`, to restrict what modules can register new accounts. This is useful if you want to allow only registration using `mod_register_web`, for example. ### PosgreSQL changes Added to PgSQL’s new schema missing SQL migration for table push\_session ([#3656](https://github.com/processone/ejabberd/pull/3656?ref=process-one.net)) Fixed in PgSQL’s new schema the vcard\_search definition ([#3695](https://github.com/processone/ejabberd/issues/3695?ref=process-one.net)). How to update an existing database: ```sql ALTER TABLE vcard_search DROP CONSTRAINT vcard_search_pkey; ALTER TABLE vcard_search ADD PRIMARY KEY (server_host, lusername); ``` ### Summary of changes: #### Commands - create\_room\_with\_opts: Fixed when using SQL storage ([#3700](https://github.com/processone/ejabberd/issues/3700?ref=process-one.net)) - change\_room\_option: Add missing fields from config inside mod\_muc\_admin:change\_options - piefxis: Fixed arguments of all commands #### Modules - mod\_caps: Don’t forget caps on XEP-0198 resumption - mod\_conversejs: New module to serve a simple page for Converse.js - mod\_http\_upload\_quota: Avoid ‘max\_days’ race - mod\_muc: Support MUC hats (XEP-0317, conversejs/prosody compatible) - mod\_muc: Optimize MucSub processing - mod\_muc: Fix exception in mucsub {un}subscription events multicast handler - mod\_multicast: Improve and optimize multicast routing code - mod\_offline: Allow storing non-composing x:events in offline - mod\_ping: Send ping from server, not bare user JID ([#3658](https://github.com/processone/ejabberd/issues/3658?ref=process-one.net)) - mod\_push: Fix handling of MUC/Sub messages ([#3651](https://github.com/processone/ejabberd/issues/3651?ref=process-one.net)) - mod\_register: New allow\_modules option to restrict registration modules - mod\_register\_web: Handle unknown host gracefully - mod\_register\_web: Use mod\_register configured restrictions ([#3688](https://github.com/processone/ejabberd/issues/3688?ref=process-one.net)) #### PubSub - Add delete\_expired\_pubsub\_items command - Add delete\_old\_pubsub\_items command - Optimize publishing on large nodes (SQL) - Support unlimited number of items - Support ‘max\_items=max’ node configuration ([#3666](https://github.com/processone/ejabberd/pull/3666?ref=process-one.net)) - Bump default value for ‘max\_items’ limit from 10 to 1000 ([#3652](https://github.com/processone/ejabberd/pull/3652?ref=process-one.net)) - Use configured ‘max\_items’ by default - node\_flat: Avoid catch-all clauses for RSM - node\_flat\_sql: Avoid catch-all clauses for RSM #### SQL - Use INSERT … ON CONFLICT in SQL\_UPSERT for PostgreSQL >= 9.5 - mod\_mam export: assign MUC entries to the MUC service ([#3680](https://github.com/processone/ejabberd/issues/3680?ref=process-one.net)) - MySQL: Fix typo when creating index ([#3654](https://github.com/processone/ejabberd/pull/3654?ref=process-one.net)) - PgSQL: Add SASL auth support, PostgreSQL 14 ([#3691](https://github.com/processone/ejabberd/issues/3691?ref=process-one.net)) - PgSQL: Add missing SQL migration for table push\_session ([#3656](https://github.com/processone/ejabberd/pull/3656?ref=process-one.net)) - PgSQL: Fix vcard\_search definition in pgsql new schema ([#3695](https://github.com/processone/ejabberd/issues/3695?ref=process-one.net)) #### Other - captcha-ng.sh: “sort -R” command not POSIX, added “shuf” and “cat” as fallback ([#3660](https://github.com/processone/ejabberd/pull/3660?ref=process-one.net)) - Make s2s connection table cleanup more robust - Update export/import of scram password to XEP-0227 1.1 ([#3676](https://github.com/processone/ejabberd/issues/3676?ref=process-one.net)) - Update Jose to 1.11.1 (the last in hex.pm correctly versioned) ## ejabberd 21.12 download & feedback As usual, the release is tagged in the Git source code repository on [Github](https://github.com/processone/ejabberd.git?ref=process-one.net). The source package and binary installers are available at [ejabberd XMPP & MQTT server download page](https://www.process-one.net/en/ejabberd/downloads/). If you suspect that you’ve found a bug, please search or fill a bug report on [Github](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### ejabberd 21.07 URL: https://www.process-one.net/blog/ejabberd-21-07/ Last updated: 2024-09-16T13:49:07.000Z When upgrading from previous versions, please notice: there is a suggested change in all **SQL databases schemas**, another suggested change specific for MySQL, an **API change** in `srg_create`, and major changes in `ejabberdctl help`. Support for rebar3 has improved to allow building an **OTP release**. And support for **Elixir** has improved to use `mix` for compilation and build releases. So, you may want to use `--with-rebar=rebar3 | mix` and benefit from those tools features over rebar. Nevertheless, rebar is still used by default, and its support will be maintained for a long time as it’s used by several automatic build processes. A more detailed explanation of those topics: ### Add missing indexes to SQL `sr_group` table The `sr_group` table in SQL databases got a new index. If you store **Shared Roster Groups** in a SQL database, you can create the index corresponding to your database type, check the example SQL queries in [the commit](https://github.com/processone/ejabberd/commit/95fa43aa96514b7e8b77fa7c29d2c0b5b1c1331a?ref=process-one.net). ### MySQL Backend Patch for scram-sha512 The MySQL database schema has improved to support scram-sha512 ([#3582](https://github.com/processone/ejabberd/issues/3582?ref=process-one.net)) If you have a MySQL database, you can update your schema with: ```sql ALTER TABLE users MODIFY serverkey varchar(128) NOT NULL DEFAULT ’’; ALTER TABLE users MODIFY salt varchar(128) NOT NULL DEFAULT ’’; ``` ### Change in `srg_create` That command API has changed the `name` argument to `label`, for coherence with the changes in the ejabberd Web Admin page. Check `ejabberdctl help srg_create` or the [API page](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net#srg-create). ### Changes in `ejabberdctl help` The `help` command has changed its usage and results. If you use that command in some automatic script, please check `ejabberdctl help` and adapt your scripts accordingly. ### Build a release using rebar3 and mix It is now possible to build a release when using rebar, rebar3 and mix. Until now this was only supported when using rebar. In this sense, a recent rebar3 binary is included with ejabberd now. For example usage, check the [Production Release](https://docs.ejabberd.im/admin/installation/?ref=process-one.net#production-release) documentation section. Are you curious about what a release is in the Erlang/OTP world? Check [Adopting Erlang](https://adoptingerlang.org/docs/production/releases/?ref=process-one.net) and [Rebar3](https://rebar3.org/docs/deployment/releases/?ref=process-one.net). ### Build a development release Now it is possible to build a development release when using rebar3 or mix. It allows running ejabberd in the local machine for development, manual testing… without installing in the system. For example usage, check the [Development Release](https://docs.ejabberd.im/admin/installation/?ref=process-one.net#development-release) documentation section. By the way, Makefile has so many targets that now there’s a summary of them: ```shell make help ``` ### Support to use mix in `configure` The `configure` script supports rebar, rebar3 and [Elixir](https://elixir-lang.org/?ref=process-one.net)‘s mix. Until now only rebar and rebar3 were supported. If you want to compile ejabberd using mix, in theory any recent Elixir version is supported. But `make rel` requires Elixir 1.10.3 or higher. Example usage: ```shell ./configure --with-rebar=mix make rel _build/prod/rel/ejabberd/bin/ejabberd start_iex ``` ### Summary of changes #### Compilation - Add **rebar3** 3.15.2 binary - Add support for mix to: `./configure --enable-rebar=mix` - Add `make dev` to build a development release with rebar3 or mix - Improved `make rel` to work with rebar3 and mix - **Hex**: Add `sql/` and `vars.config` to Hex package files ([#3251](https://github.com/processone/ejabberd/issues/3251?ref=process-one.net)) - **Hex**: Update mix applications list to fix error `p1_utils is listed as both...` - There are so many targets in Makefile… add `make help` - Fix `extauth.py` failure in test suite with Python 3 ([#3612](https://github.com/processone/ejabberd/issues/3612?ref=process-one.net)) - Added experimental support for **GitHub Codespaces** - Switch test service from TravisCI to **GitHub Actions** ([#3613](https://github.com/processone/ejabberd/issues/3613?ref=process-one.net)) #### Commands: - Display extended error message in **ejabberdctl** ([#3584](https://github.com/processone/ejabberd/issues/3584?ref=process-one.net)) - Remove SMP option from ejabberdctl.cfg, `-smp` was removed in OTP 21 ([#3560](https://github.com/processone/ejabberd/issues/3560?ref=process-one.net)) - `create_room`: After creating room, store in DB if it’s persistent ([#3632](https://github.com/processone/ejabberd/issues/3632?ref=process-one.net)) - `help`: Major changes in its usage and output ([#3569](https://github.com/processone/ejabberd/issues/3569?ref=process-one.net)) - `srg_create`: Update to use `label` parameter instead of `name` ([#3578](https://github.com/processone/ejabberd/issues/3578?ref=process-one.net)) #### Modules: - `ejabberd_listener`: New `send_timeout` option - `mod_mix`: Improvements to update to 0.14.1 ([#3634](https://github.com/processone/ejabberd/issues/3634?ref=process-one.net)) - `mod_muc_room`: Don’t leak owner JIDs ([#3615](https://github.com/processone/ejabberd/issues/3615?ref=process-one.net)) - `mod_multicast`: Routing for more MUC packets - `mod_multicast`: Correctly strip only other bcc addresses ([#3639](https://github.com/processone/ejabberd/issues/3639?ref=process-one.net)) - `mod_mqtt`: Allow shared roster group placeholder in mqtt topic ([#3566](https://github.com/processone/ejabberd/issues/3566?ref=process-one.net)) - `mod_pubsub`: Several fixes when using PubSub with RSM ([#3618](https://github.com/processone/ejabberd/issues/3618?ref=process-one.net))([#3621](https://github.com/processone/ejabberd/issues/3621?ref=process-one.net)) - `mod_push`: Handle MUC/Sub events correctly ([#3565](https://github.com/processone/ejabberd/issues/3565?ref=process-one.net)) - `mod_shared_roster`: Delete cache after performing change to be sure that in cache will be up to date data ([#3578](https://github.com/processone/ejabberd/issues/3578?ref=process-one.net)) - `mod_shared_roster`: Improve database and caching - `mod_shared_roster`: Reconfigure cache when options change - `mod_vcard`: Fix invalid\_encoding error when using extended plane characters in vcard - `mod_vcard`: Update econf:vcard() to generate correct vcard\_temp record - **Translations**: Major improvements in the Indonesian and Portuguese translations - **WebAdmin**: New simple pages to view mnesia tables information and content - **WebSocket**: Fix typos ([#3622](https://github.com/processone/ejabberd/issues/3622?ref=process-one.net)) #### SQL: - MySQL Backend Patch for **scram-sha512** ([#3582](https://github.com/processone/ejabberd/issues/3582?ref=process-one.net)) - **SQLite**: When exporting for SQLite, use its specific escape options ([#2576](https://github.com/processone/ejabberd/issues/2576?ref=process-one.net)) - **SQLite**: Minor fixes for new\_sql\_schema support ([#3303](https://github.com/processone/ejabberd/issues/3303?ref=process-one.net)) - `mod_privacy`: Cast as boolean when exporting privacy\_list\_data to **PostgreSQL** ([#1773](https://github.com/processone/ejabberd/issues/1773?ref=process-one.net)) - `mod_mqtt`: Add mqtt\_pub table definition for **MSSQL** ([#3097](https://github.com/processone/ejabberd/issues/3097?ref=process-one.net)) - `mod_shared_roster`: Add missing indexes to `sr_group` tables in all SQL databases ## ejabberd 21.07 download & feedback As usual, the release is tagged in the Git source code repository on [Github](https://github.com/processone/ejabberd.git?ref=process-one.net). The source package and binary installers are available at [ejabberd XMPP & MQTT server download page](https://www.process-one.net/en/ejabberd/downloads/). If you suspect that you’ve found a bug, please search or fill a bug report on [Github](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Install ejabberd on Windows 7 using Docker Toolbox URL: https://www.process-one.net/blog/install-ejabberd-on-windows-7-using-docker-toolbox/ Last updated: 2024-09-16T14:11:20.000Z Did you read our previous tutorial [how to install ejabberd on Windows 10 using Docker Desktop](https://www.process-one.net/blog/install-ejabberd-on-windows-10-using-docker-desktop/)? Do you have a Microsoft system older than Windows 10? Don’t worry, instead of Docker Desktop you can use Docker Toolbox, and this tutorial guides you over the process. This tutorial explains how to get any ejabberd version installed on Microsoft Windows 7 or 8 (and probably others) 64bits using Docker Toolbox and *ejabberd-docker-install.bat*. Docker Toolbox is an old and obsolete program, suitable for Microsoft systems older than Windows 10\. If you have Windows 10, you will surely prefer to use Docker Desktop, check our tutorial [how to install ejabberd on Windows 10 using Docker Desktop](https://www.process-one.net/blog/install-ejabberd-on-windows-10-using-docker-desktop/). ## 1\. Install Docker Toolbox First, download and install [Docker Toolbox](https://github.com/docker/toolbox/releases?ref=process-one.net), specifically the file *DockerToolbox-19.03.1.exe*. The process is pretty straightforward, and it will ask you to restart your machine. After installing that file, you will get several icons in your desktop: ![Install Docker Toolbox](https://www.process-one.net/wp-content/uploads/2021/03/docker-win7-step1.png) Now run *Docker Quickstart*. It will take some time to complete. ## 2\. Download ejabberd-docker-install.bat Download [ejabberd-docker-install.bat](https://raw.githubusercontent.com/processone/docker-ejabberd/master/ecs/ejabberd-docker-install.bat?ref=process-one.net) to your machine. ## 3\. Edit some install options Edit this batch file with your favourite text editor and set at least the `PASSWORD` option for the new administrator account. Additionally, you can set some other options: `HOST`, `USER`, `VERSION`, and `PORTS`. Please notice that you cannot configure the installation directory. The reason is that Docker Toolbox can only mount volumes from `C:/Users/Your-User`. So, the script must install your ejabberd files there. ## 4\. Run the script When you run the script it will open a console window to inform what it is doing: download the ejabberd image, create the container, register the admin account and prepare the configuration file… If installation completes correctly, you can close that window and proceed to next step. ![Run the script](https://www.process-one.net/wp-content/uploads/2021/03/4-recortado.png) If there was any error, solve it and run the script again. You can delete the script and download it again, or delete the ejabberd container, or delete the ejabberd installed directory… and run the script again. ## 5\. Start ejabberd Now you can finally go to *Kitematic (alpha)*, where you can see the new `ejabberd` container. Simply click the “Start” icon to run this container: ![Start ejabberd](https://www.process-one.net/wp-content/uploads/2021/03/docker-win7-step5a.png) ![Start ejabberd](https://www.process-one.net/wp-content/uploads/2021/03/docker-win7-step5b.png) After a few seconds, ejabberd is started in that container and accepting connections. ![](https://www.process-one.net/wp-content/uploads/2021/03/docker-win7-step5c-result.png) ## Next steps If you are here it means you have ejabberd installed and running in your machine, and you may be asking yourself how to administrate it. Here are some remarks: ### ejabberd.yml, database and logs The configuration files, Mnesia internal database `spool` and `logs` directory are available for you to edit and inspect in Windows, in `C:/Users/your user/ejabberd`. There is also a `ejabberd-modules` directory where you can later put additional modules from `ejabberd-contrib`, or any other place. Whenever you update to a newer ejabberd, it is a good practice to backup the `conf` and `database` directories. ![ejabberd.yml, database and logs](https://www.process-one.net/wp-content/uploads/2021/03/docker-win7-volumes-e1617111247346.png) ### ejabberd WebAdmin To open a web browser pointing to ejabberd webadmin, go to *Settings » Hostname/Ports* and click on the 5180 port. Alternatively, you can open it yourself by going to `` http://localhost:5180` (swap ``localhost`for the value of the`HOST\` variable if you changed it in the installation script). You will be welcomed by a browser authentication prompt, where you should type in the login details defined in the installation script: `USER@HOST` and `PASSWORD`. You will then see the usual ejabberd webadmin console, where you can easily manage your server instance. That’s it! ![ejabberd WebAdmin](https://www.process-one.net/wp-content/uploads/2021/03/docker-win7-webadmin-e1617111287456.png) ### CLI with ejabberdctl The EXEC icon opens a console in the ejabberd container where you can use ejabberdctl, and that means you can use any [ejabberd Administration API](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net). ![CLI with ejabberdctl](https://www.process-one.net/wp-content/uploads/2021/03/docker-win7-ctl-e1617111329178.png) ### ejabberd-contrib In addition to the modules already included in ejabberd releases, there are several more published in [ejabberd-contrib repo](https://github.com/processone/ejabberd-contrib?ref=process-one.net), and many other in internet if you search, and you can even [write your own modules](https://docs.ejabberd.im/developer/extending-ejabberd/modules/?ref=process-one.net). To start with all this, open a CLI as explained previously, and execute: ```bash bin/ejabberdctl modules_update_specs ``` For the next steps, check [this ejabberd-contrib documentation](https://docs.ejabberd.im/developer/extending-ejabberd/modules/?ref=process-one.net#ejabberd-contrib). ### Update from old binary installer If you already have ejabberd installed using a binary installer downloaded from ProcessOne website: 1. Stop ejabberd using the “Stop ejabberd” desktop shortcut as usual 2. It is always a good practice to backup the `conf` and `database` directories. 3. Uninstall ejabberd 4. Follow the steps described in this tutorial 5. Check ejabberd runs perfectly with the basic configuration and empty database. Now it’s time to get back your configuration and database: 1. Stop ejabberd in the Docker Desktop 2. Copy your old `conf` and `database` directories to the new location 3. Start ejabberd and check if it runs correctly now too. ### Update to a new ejabberd version When a new ejabberd version is released, go to [ejabberd Docker Hub](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net), and check if the new version is available in Tags. How to install it? 1. Delete your old `ejabberd` container 2. Edit the `VERSION` option in *ejabberd-docker-install.bat* 3. And run the script It will download the new image and create a new container. ## If something goes terribly wrong As mentioned previously, if something goes terribly wrong, don’t worry! You can delete the script, or the installed directory, or the ejabberd container, and start from scratch. ## Docker Desktop in macOS and Linux Docker Desktop is also available for the macOS and Linux systems. While the above installation script is designed for Windows, it could be modified for these other platforms as well. This means you now have several methods of installing and running ejabberd on any given operating system: using a package manager (like `apt` on Debian or `brew` on macOS), using a Docker container, with a binary installer (on Linux) or building from source. ## Questions, problems, suggestions The batch script to use Docker and this tutorial may have issues or mistakes. Please add a comment here, or join the ejabberd chatroom, or send an email to the [ejabberd mailing list](http://lists.jabber.ru/mailman/listinfo/ejabberd?ref=process-one.net) or fill a bug/suggestion in the [ejabberd tracker](https://github.com/processone/ejabberd/issues?ref=process-one.net) or [docker-ejabberd trackers](https://github.com/processone/docker-ejabberd?ref=process-one.net). *Photo by* [*Rinson Chory*](https://unsplash.com/photos/aJgw1jeJcEY?ref=process-one.net) *on Unsplash* ### ejabberd 21.04 URL: https://www.process-one.net/blog/ejabberd-21-04/ Last updated: 2024-09-16T14:11:38.000Z There are no configuration, hooks or API changes that require attention when upgrading. Nonetheless, there’s a new API command (`get_user_subscriptions`), a new configure option (`--enable-lua`), and an improvement in the MySQL database definition. ## MySQL database definition improvement We updated the database definition to fix the “specified key was too long” warnings. By default, the new character set and collation (`utf8mb4` and `utf8mb4_unicode_ci`) will only be used with newly created databases. The existing installations don’t need to convert anything. However, if you feel like it, after you upgrade to ejabberd 21.04, you can apply the following SQL command to convert your existing MySQL database character set to the latest definition: ```sql alter table push_session convert to character set utf8mb4 collate utf8mb4_unicode_ci; alter table mqtt_pub convert to character set utf8mb4 collate utf8mb4_unicode_ci; ``` ## Windows support As you may have noticed, the last binary installer for Windows is from a year ago. Since then, the recommended method to install ejabberd on Windows is using the ejabberd Docker image, and we’ve just published two tutorials on how to do it: - [How to install ejabberd on Windows 10 using Docker Desktop](https://www.process-one.net/blog/install-ejabberd-on-windows-10-using-docker-desktop/) - [How to install ejabberd on Windows 7 (or 8) using Docker Toolbox](https://www.process-one.net/blog/install-ejabberd-on-windows-7-using-docker-toolbox/) ## ejabberd 21.04 download & feedback As usual, the release is tagged in the Git source code repository on [Github](https://github.com/processone/ejabberd?ref=process-one.net). The source package and binary installers are available at [ejabberd XMPP & MQTT server download page](https://www.process-one.net/en/ejabberd/downloads/). If you suspect that you’ve found a bug, please search or fill a bug report on [Github](https://github.com/processone/ejabberd/issues?ref=process-one.net). ## A detailed list of changes ### API Commands - `add_rosteritem/...`: Add argument guards to roster commands - `get_user_subscriptions`: New command for MUC/Sub - `remove_mam_for_user_with_peer`: Fix when removing room archive - `send_message`: Fix bug introduced in ejabberd 21.01 - `set_vcard`: Return modules errors ### Build and setup - Allow ejabberd to be compatible as a dependency for an Erlang project using rebar3 - CAPTCHA: New question/answer-based CAPTCHA script - `--enable-lua`: new configure option for luerl instead of –enable-tools - Remove support for HiPE, it was experimental and Erlang/OTP 24 removes it - Update `sql_query` record to handle the Erlang/OTP 24 compiler reports - Updated dependencies to fix Dialyzer warnings ### Miscellaneous - CAPTCHA: Update `FORM_TYPE` from captcha to register - LDAP: fix eldap certificate verification - MySQL: Fix for “specified key was too long” - Translations: updated the Esperanto, Greek, and Japanese translations - Websocket: Fix PONG responses ### Modules: - `mod_block_strangers`: If stanza is type error, allow it passing - `mod_caps`: Don’t request roster when not needed - `mod_caps`: Skip reading roster in one more case - `mod_mam`: Remove `queryid` from MAM fin element - `mod_mqtt`: When deregistering XMPP account, close its MQTT sessions - `mod_muc`: Take in account subscriber’s affiliation when checking access to moderated room - `mod_muc`: Use monitors to track online and hard-killed rooms - `mod_muc`: When occupant is banned, remove his subscriptions too - `mod_privacy`: Make fetching roster lazy - `mod_pubsub`: Don’t fail on PEP unsubscribe - `mod_pubsub`: Fix `gen_pubsub_node:get_state` return value - `mod_vcard`: Obtain and provide photo type in vCard LDAP ### Install ejabberd on Windows 10 using Docker Desktop URL: https://www.process-one.net/blog/install-ejabberd-on-windows-10-using-docker-desktop/ Last updated: 2024-09-16T14:17:32.000Z This tutorial requires Windows 10 or newer. For older systems like Windows 7 or 8, follow the tutorial on [how to install ejabberd on Windows 7 using Docker Toolbox](https://www.process-one.net/blog/install-ejabberd-on-windows-7-using-docker-toolbox/). For some time now we have been phasing out the traditional installation wizards, customary to the end users on macOS and Windows, in favor of the more streamlined command line approach, well known on Linux desktops and servers. First, we have phased out the macOS binary installer in favor of a quick `brew install ejabberd` command. Then, since ejabberd 20.07, we have phased out the Windows installer in favor of a container solution. However, setting ejabberd in Docker requires setting volumes, ports and some customizations, so we’ve written a batch script that performs all those tasks for you. This tutorial explains how to get any ejabberd version installed on Microsoft Windows 10 using Docker Desktop and *ejabberd-docker-install.bat* script. Docker Desktop is only available for Windows 10\. If you use Windows 7 or 8, you can use Docker Toolbox, which is old and obsolete, but it still seems to work correctly, so give it a try. We published a tutorial explaining [how to install ejabberd on Windows 7 using Docker Toolbox](https://www.process-one.net/blog/install-ejabberd-on-windows-7-using-docker-toolbox/). ## 1\. Install Docker Desktop First of all, download and install [Docker Desktop](https://www.docker.com/products/docker-desktop?ref=process-one.net) for Windows. The process is pretty straightforward, and it will ask you to restart your machine. The installation wizard may ask you to install Microsoft’s WSL2 and restart the Docker Desktop app. ## 2\. Download ejabberd-container-install.bat Download [ejabberd-container-install.bat](https://raw.githubusercontent.com/processone/ejabberd/master/.github/container/ejabberd-container-install.bat?ref=process-one.net) to your machine. ## 3\. Edit the install options Edit this batch file with your favorite text editor and set, at the very least, the `PASSWORD` option you want for your new ejabberd administrator account. Additionally, you can set some other options: `INSTALL_DIR_WINDOWS10`, `HOST`, `USER`, `VERSION`, and `PORTS`. ## 4\. Run the script When you run the script, it will open a console window to inform you about the process: download the ejabberd image, create the container, register the admin account and prepare the configuration file… If installation completes correctly, you can close that window and proceed to next step. ![Run the script](https://www.process-one.net/wp-content/uploads/2021/03/4-recortado.png) If there was any error, solve it and run the script again. You can delete the script and download it again, or delete the ejabberd container, or delete the ejabberd installed directory… and run the script again. ## 5\. Start ejabberd Now you can finally go to Docker Desktop, where you can see the new `ejabberd` container, and click the “Start” icon: ![Start ejabberd](https://www.process-one.net/wp-content/uploads/2021/03/5-recortado-1.png) Wait a few seconds till ejabberd is started in that container and accepting connections: ![Running ejabberd](https://www.process-one.net/wp-content/uploads/2021/03/5b-recortado.png) ## Next steps At this point, you have ejabberd installed and running on your machine, and you may be asking yourself how to administrate it. Here are some remarks: ### ejabberd.yml, database and logs The configuration files, Mnesia internal database *spool* and *logs* directories are available for you to edit and inspect in Windows, in the path that you specified in the `INSTALL_DIR_WINDOWS10` option. There is also an *ejabberd-modules* directory, where you can later put additional modules from [ejabberd-contrib](https://github.com/processone/ejabberd-contrib?ref=process-one.net), or any other place. Whenever you update to a newer ejabberd, it is a good practice to backup the *conf* and *database* directories. ![ejabberd.yml, database and logs](https://www.process-one.net/wp-content/uploads/2021/03/mounts-recortado-1.png) ### ejabberd WebAdmin The “Open in browser” icon will open a browser with the ejabberd webadmin page. Alternatively, you can open it yourself by going to `http://localhost:5180` (swap `localhost` for the value of the `HOST` variable, if you changed it in the installation script). You will be welcomed by a browser authentication prompt, where you should type in the login details defined in the installation script: `USER@HOST` and `PASSWORD`. You will then see the usual ejabberd webadmin console, where you can easily manage your server instance. ![ejabberd WebAdmin](https://www.process-one.net/wp-content/uploads/2021/03/webadmin-recortada-e1617096806610.png) ### CLI with ejabberdctl The next icon opens a console in the ejabberd container where you can use ejabberdctl, and that means you can use any [ejabberd Administration API](https://docs.ejabberd.im/developer/ejabberd-api/admin-api/?ref=process-one.net). ![CLI with ejabberdctl](https://www.process-one.net/wp-content/uploads/2021/03/ctl-recortado-e1617096841527.png) ### ejabberd-contrib In addition to the modules already included in ejabberd releases, there are several more published in [ejabberd-contrib](https://github.com/processone/ejabberd-contrib?ref=process-one.net), and many other on the internet, and you can even [write your own modules](https://docs.ejabberd.im/developer/extending-ejabberd/modules/?ref=process-one.net). To start with all this, open the CLI as explained previously, and execute: ```bash bin/ejabberdctl modules_update_specs ``` For the next steps, check [this ejabberd-contrib documentation](https://docs.ejabberd.im/developer/extending-ejabberd/modules/?ref=process-one.net#ejabberd-contrib). ### Update from old binary installer If you already have ejabberd installed using a binary installer downloaded from ProcessOne website: 1. Stop ejabberd using the “Stop ejabberd” desktop shortcut as usual 2. It is always a good practice to backup the *conf* and *database* directories 3. Uninstall ejabberd 4. Follow the steps described in this tutorial 5. Check that ejabberd runs perfectly with the basic configuration and empty database Now it’s time to get back your configuration and database: 1. Stop ejabberd in the Docker Desktop 2. Copy your old *conf* and *database* directories to the new location 3. Start ejabberd and check if it runs correctly ### Update to a new ejabberd version When a new ejabberd version is released, go to [ejabberd Docker Hub](https://hub.docker.com/r/ejabberd/ecs/?ref=process-one.net), and check if the new version is available in Tags. How to install it? 1. Delete your old `ejabberd` container 2. Edit the `VERSION` option in *ejabberd-docker-install.bat* 3. Run the script It will download the new image and create a new container. ### If something goes terribly wrong As mentioned previously, if something goes terribly wrong, don’t worry! You can delete the script, or the installed directory, or the ejabberd container, and start from scratch. ## Docker Desktop in macOS and Linux Docker Desktop is also available for the macOS and Linux systems. While the above installation script is designed for Windows, it could be modified for these other platforms as well. This means you now have several methods of installing and running ejabberd on any given operating system: using a package manager (like `apt` on Debian or `brew` on macOS), using a Docker container, with a binary installer (on Linux) or building from source. ## Questions, problems, suggestions The batch script to use Docker and this tutorial may have problems or errors. So, please add a comment here, or join the ejabberd chatroom, or send an email to the [ejabberd mailing list](http://lists.jabber.ru/mailman/listinfo/ejabberd?ref=process-one.net) or fill a bug/suggestion in the [ejabberd tracker](https://github.com/processone/ejabberd/issues?ref=process-one.net) or [docker-ejabberd trackers](https://github.com/processone/docker-ejabberd?ref=process-one.net). *Photo by* [*Frank Mckenna*](https://unsplash.com/photos/tjX%5FsniNzgQ?ref=process-one.net) *on Unsplash* ### Publish-Subscribe pattern and PubSub in ejabberd URL: https://www.process-one.net/blog/publish-subscribe-pattern-and-pubsub-in-ejabberd/ Last updated: 2024-09-16T14:21:55.000Z Publish–Subscribe is a messaging pattern where senders of messages, called *publishers*, do not send the messages directly to specific receivers, called *subscribers*. Instead, publishers categorize messages into channels without knowledge of which subscribers, if any, there may be. Similarly, subscribers express interest in one or more channels and only receive messages that are of interest, without knowledge of which publishers, if any, there are. > **» Don’t want to configure PubSub yourself?** > ProcessOne experts will make your business instantly connected. [Contact us »](https://www.process-one.net/en/company/contact) # ejabberd and PubSub In case of ejabberd, the Publish-Subscribe pattern (PubSub) is implemented by the native module `mod_pubsub`. From the outside, it works very similar to ejabberd MQTT module `mod_mqtt`. However, `mod_pubsub` uses XML and `iq` stanzas for communication. Therefore, [ejabberd PubSub](https://www.process-one.net/blog/ejabberd%5Fpubsub%5Ffeatures/) brings all the advantages as well as complexities that come with XML. # Create a PubSub node Before we start, make sure you are using an XMPP client that has an option of sending raw XML input to your server. One of such clients is [Psi](https://github.com/psi-im/psi?ref=process-one.net), available for many platforms. Next, we need to keep in mind that in ejabberd `mod_pubsub` is enabled by default with plugins `flat` and `pep`. The permission to create nodes is limited to local accounts. To create your first node, send the following command using the “XML Input” within the Psi XML Console. Substitute `marekfoss.org` in `to` and `node` params with your server domain, and `mf` in the `/home/marekfoss.org/mf/open` with your username. The node in this example is called `open`. ```xml ``` To verify that the node was created, you can send the above command again, at which point you should get a 409 error saying “Node already exists”. To create more nodes, remember to increment or change the `id` value of the `iq` element, like `create1`, `create2` etc. and change the node’s name in the `/home/marekfoss.org/mf/...` path. Please note that the correct node path: `/home/[domain]/[username]/[nodename]` is important. With the default `mod_pubsub` permissions, the plugin will allow you to create this node. If you would like to create your node in another path, [refer to the docs](https://docs.ejabberd.im/archive/20%5F04/modules/?ref=process-one.net#mod-pubsub). # Subscribe the PubSub client Now we can subscribe our client to receive messages from the node we just created. To do this, we use the following command, where we `subscribe` the specified `jid` to the specified `node`: ```xml ``` If successful, you should see in your XML terminal a response containing a section like this: ```xml ``` # Publish with PubSub client Now we can test our new PubSub communication channel by sending the first message to the node we created. To do this, we use the following command: ```xml Hello Brave New World To be, or not to be: that is the question: Whether 'tis nobler in the mind to suffer The slings and arrows of outrageous fortune, Or to take arms against a sea of troubles, And by opposing end them? ``` In response, you should see the message relied back to you, as well as an acknowledgement looking like the following: ```xml ``` When publishing, the `item` `entry` can contain more tags with things like dates, links etc. Please refer to [this post](https://www.ejabberd.im/mod%5Fpubsub-usage/index.html?ref=process-one.net) for more examples. # What can we do with ejabberd PubSub? If you look at the [ejabberd PubSub features](https://www.process-one.net/blog/ejabberd%5Fpubsub%5Ffeatures/) you can see that it contains a vast amount of options at your disposal, like fine-grained authorization, subscription monitoring and management, message retractions and more. When you compare it to the earlier [tutorial on ejabberd MQTT broker](https://www.process-one.net/blog/starting-with-mqtt-protocol-and-ejabberd-mqtt-broker/), you can see a much wider range of features available out-of-the-box when using PubSub. In this ejabberd tutorial series: - [How to move the office to ejabberd XMPP server](https://www.process-one.net/blog/how-to-move-the-office-to-real-time-im-on-ejabberd/) - [How to set up ejabberd video & voice calling (STUN/TURN)](https://www.process-one.net/blog/how-to-set-up-ejabberd-video-voice-calling/) - [How to configure ejabberd to get 100% in XMPP compliance test](https://www.process-one.net/blog/how-to-configure-ejabberd-to-get-100-in-xmpp-compliance-test/) - [Check ejabberd XMPP server useful configuration steps](https://www.process-one.net/blog/ejabberd-xmpp-server-useful-configuration-steps/) - [Starting with MQTT protocol and ejabberd MQTT broker](https://www.process-one.net/blog/starting-with-mqtt-protocol-and-ejabberd-mqtt-broker/) - [Getting started with WebSocket API in ejabberd](https://www.process-one.net/blog/getting-started-with-websocket-api-in-ejabberd/) - [Install and configure MariaDB with ejabberd](https://www.process-one.net/blog/install-and-configure-mariadb-with-ejabberd/) - [Publish-Subscribe pattern and PubSub in ejabberd](https://www.process-one.net/blog/publish-subscribe-pattern-and-pubsub-in-ejabberd/) *Photo by* [*Sawyer Bengtson*](https://unsplash.com/photos/YaSH0DbU5lE?ref=process-one.net) *on Unsplash* ### Install and configure MariaDB with ejabberd URL: https://www.process-one.net/blog/install-and-configure-mariadb-with-ejabberd/ Last updated: 2024-09-16T14:26:18.000Z By default, ejabberd uses the Mnesia internal database. It is great for home and small office environments, but in larger companies, as the amount of chat logs and users grows, we need more scalability. Today, I will show you how to install MariaDB, a MySQL-compatible database, migrate your data and configure ejabberd to use MariaDB instead of Mnesia. > **» Don’t want to migrate data yourself?** > ProcessOne experts will make your communication scalable. [Contact us »](https://www.process-one.net/en/company/contact) ## Installing MariaDB We assume the usual Debian configuration as in my previous tutorials. I have updated my ejabberd to version 21.01 (the update process is the same as the initial ejabberd installation, so [check my first tutorial](https://www.process-one.net/blog/how-to-move-the-office-to-real-time-im-on-ejabberd/)). To install MariaDB simply use: ```bash apt-get install mariadb-server ``` Then run the installation wizard and follow the instructions: ```bash mysql_secure_installation ``` ## Preparing MariaDB for ejabberd To get MariaDB ready for ejabberd, we need to create a new database, its user, and then populate the database with the ejabberd SQL schema. First, let’s create the database using your MariaDB `root` user: ```bash echo "CREATE DATABASE ejabberd;" | mysql -h localhost -u root -p ``` Next, let’s create a dedicated `ejabberd` user authenticated with a `password`, and assign it to this database. The `Enter password` prompt is again asking about the `root` MariaDB user: ```bash echo "GRANT ALL ON ejabberd.* TO 'ejabberd'@'localhost' IDENTIFIED BY 'password';" | mysql -h localhost -u root -p ``` Finally, let’s download the latest ejabberd SQL schema and load it into our database. This time, we are switching to using the `ejabberd` MariaDB user, and the `Enter password` prompt is asking for the `password` we just specified in the `GRANT` command above: ```bash wget https://raw.githubusercontent.com/processone/ejabberd/master/sql/mysql.sql mysql -h localhost -D ejabberd -u ejabberd -p < mysql.sql ``` To verify that everything is correct, run a command to display all the database tables, again using the `ejabberd` MariaDB user, and the output should look something like that: ```bash echo "SHOW TABLES;" | mysql -h localhost -D ejabberd -u ejabberd -p --table Enter password: +-------------------------+ | Tables_in_ejabberd | +-------------------------+ | archive | | archive_prefs | | bosh | | caps_features | | last | | mix_channel | | mix_pam | | mix_participant | | mix_subscription | | motd | | mqtt_pub | ... ``` ## Configuring ejabberd for MariaDB Now that our MariaDB tables are ready, we need to configure ejabberd to use this MySQL-compatible database. Edit your `ejabberd.yml` config and add the following settings, where `password` refers to the `ejabberd` MariaDB user: ```yaml sql_type: mysql sql_server: "localhost" sql_database: "ejabberd" sql_username: "ejabberd" sql_password: "password" ``` ## Migrating Mnesia data to MariaDB database At this point, if you restart your ejabberd, it won’t be using MariaDB just yet. Let’s first migrate Mnesia data into our new SQL database using `ejabberdctl` – we first export the data into a `mnesia.sql` file, and then we import it into the MariaDB database: ```bash cd /opt/ejabberd-21.01/bin/ ./ejabberdctl export2sql marekfoss.org /tmp/mnesia.sql mysql -h localhost -D ejabberd -u ejabberd -p < /tmp/mnesia.sql rm /tmp/mnesia.sql ``` It’s a good practice to remove the `/tmp/mnesia.sql` after we are done with it. Now, add `default_db: sql` and `auth_method: sql` to your `ejabberd.yml` configuration file: ```yaml default_db: sql auth_method: sql sql_type: mysql sql_server: "localhost" sql_database: "ejabberd" sql_username: "ejabberd" sql_password: "password" ``` Then, restart your ejabberd instance – it will now use the MariaDB database! Please note that the Mnesia database will still be started up and used for non-persistent data and clustering. In this ejabberd tutorial series: - [How to move the office to ejabberd XMPP server](https://www.process-one.net/blog/how-to-move-the-office-to-real-time-im-on-ejabberd/) - [How to set up ejabberd video & voice calling (STUN/TURN)](https://www.process-one.net/blog/how-to-set-up-ejabberd-video-voice-calling/) - [How to configure ejabberd to get 100% in XMPP compliance test](https://www.process-one.net/blog/how-to-configure-ejabberd-to-get-100-in-xmpp-compliance-test/) - [Check ejabberd XMPP server useful configuration steps](https://www.process-one.net/blog/ejabberd-xmpp-server-useful-configuration-steps/) - [Starting with MQTT protocol and ejabberd MQTT broker](https://www.process-one.net/blog/starting-with-mqtt-protocol-and-ejabberd-mqtt-broker/) - [Getting started with WebSocket API in ejabberd](https://www.process-one.net/blog/getting-started-with-websocket-api-in-ejabberd/) - [Install and configure MariaDB with ejabberd](https://www.process-one.net/blog/install-and-configure-mariadb-with-ejabberd/) - [Publish-Subscribe pattern and PubSub in ejabberd](https://www.process-one.net/blog/publish-subscribe-pattern-and-pubsub-in-ejabberd/) *Photo by* [*Amy Asher*](https://unsplash.com/photos/giZJHm2m9yY?ref=process-one.net) *on Unsplash* ### ejabberd 21.01 URL: https://www.process-one.net/blog/ejabberd-21-01/ Last updated: 2024-09-16T14:30:18.000Z Six weeks after previous release, [ejabberd 21.01](https://www.process-one.net/en/ejabberd/downloads/) contains as usual several improvements and bugfixes. There are no changes required in the API, configuration or databases. ## Fixed sqlite3 dependency version erlang-sqlite3 versions got messed up, causing ejabberd build to regress to 1.1.6 from Jan 2018 when using rebar3 which fails to build with OTP23\. Update to correctly tagged version 1.1.9, which also has matching hex.pm package, fixes this. ## Integrate nicely with systemd Support systemd’s watchdog feature and enable it by default in the unit file, so that ejabberd is auto-restarted if the VM becomes unresponsive. Also, set the systemd startup type to ‘notify’, so that startup of followup units is delayed until ejabberd signals readiness. While at it, also notify systemd of configuration reload and shutdown states. Note: `NotifyAccess=all` is required as long as `ejabberdctl foreground` runs the VM as a new child process, rather than “exec”ing it. This way, systemd views the ejabberdctl process itself as the main service process, and would discard notifications from other processes by default. ## New `ejabberdctl foreground-quiet` This starts ejabberd without detaching the process, but setups console logging to display only critical messages. ## STUN The ‘stun’ application now rejects Teredo and 6to4 TURN peers unconditionally. Therefore, remove those networks from the default ‘turn\_blacklist’. Block loopback addresses by default: Don’t accept loopback addresses as TURN peers by default. This makes sure the TURN service won’t allow remote clients to access local UDP services. However, this will break the case where the `turn_ipv4_address` was set to `127.0.0.1` as fallback and TURN worked “by accident” if both clients were using the same TURN service. The service then talked to itself on the loopback interface. ## Translations The gettext-formatted PO files are now located in a specific repository, [ejabberd-po](https://github.com/processone/ejabberd-po?ref=process-one.net), and have been published with MIT license. This allows translators continue improving them, and be included in ejabberd packages without requiring the translators so sign a Contribution License Agreement. ## Summary of changes: ### Miscellaneous: - log\_rotate\_size option: Fix handling of ‘infinity’ value - mod\_time: Fix invalid timezone - Auth JWT: New check\_decoded\_jwt hook runs the default JWT verifier - MUC: Allow non-occupant non-subscribed service admin send private MUC message - MUC: New max\_password and max\_captcha\_whitelist options - OAth: New oauth\_cache\_rest\_failure\_life\_time option - PEP: Skip reading pep nodes that we know won’t be requested due to caps - SQL: Add sql script to migrate mysql from old schema to new - SQL: Don’t use REPLACE for upsert when there are “-” fields. - Shared Rosters LDAP: Add multi-domain support (and flexibility) - Sqlite3: Fix dependency version - Stun: Block loopback addresses by default - Several documentation fixes and clarifications ### Commands: - decide\_room: Use better fallback value for room activity time when skipping room - delete\_old\_message: Fix when using sqlite spool table - module\_install: Make ext\_mod compile module with debug\_info flags - room\_unused\_\*: Don’t fetch subscribers list - send\_message: Don’t include empty in messages - set\_room\_affiliation: Validate affiliations ### Running: - Docker: New Dockerfile and devcontainer.json - New ‘ejabberdctl foreground-quiet’ - Systemd: Allow for listening on privileged ports - Systemd: Integrate nicely with systemd ### Translations: - Moved gettext PO files to a new ejabberd-po repository - Improved several translations: Catalan, Chinese, German, Greek, Indonesian, Norwegian, Portuguese (Brazil), Spanish. ## ejabberd 21.01 download & feedback As usual, the release is tagged in the Git source code repository on [Github](https://github.com/processone/ejabberd.git?ref=process-one.net). The source package and binary installers are available at [ejabberd XMPP & MQTT server download page](https://www.process-one.net/en/ejabberd/downloads/). We’ve discovered some issues with the Windows installer that we are still working on, so its publication is delayed. If you suspect that you’ve found a bug, please search or fill a bug report on [Github](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### ejabberd 20.12 URL: https://www.process-one.net/blog/ejabberd-20-12/ Last updated: 2024-09-16T14:33:27.000Z We are pleased to announce [ejabberd 20.12](https://www.process-one.net/en/ejabberd/downloads/). This release, just in time for the New Year’s, includes several new features and many improvements & bugfixes. Most notably, ejabberd now works with the Microsoft ODBC Driver for the SQL Server support. With [a new config option](https://docs.ejabberd.im/admin/configuration/database-ldap/?ref=process-one.net#microsoft-sql-server), `sql_odbc_driver`, you can explicitly specify the path to the ODBC driver you want to use. We also improved the supported authentication methods with the addition of SCRAM-SHA-1-PLUS, SCRAM-SHA-256(-PLUS) and SCRAM-SHA-512(-PLUS). ejabberd 20.12 is a big release, and here is just a small selection of the improvements it includes: ## Core: - Add support for SCRAM-SHA-(1,256,512)(-PLUS) authentication - Don’t use same value in cache for user don’t exist and wrong password - `outgoing_s2s_ipv*_address`: New options to set ipv4/ipv6 outbound s2s out interface - `s2s_send_packet`: this hook now filters outgoing s2s stanzas - `start_room`: new hook runs when a room process is started - `check_decoded_jwt`: new hook to check decoded JWT after success authentication ## Admin - Docker: Fix DB initialization - New `sql_odbc_driver` option: choose the mssql ODBC driver, with support for Microsoft ODBC Driver for SQL Server - Rebar3: Fully supported. Enable with `./configure --with-rebar=/path/to/rebar3` - systemd: start ejabberd in foreground ## Modules: - MAM: Make sure that jid used as base in mam xml\_compress is bare - MAM: Support for MAM Flipped Pages - MUC: Always show MucSub subscribers nicks - MUC: Don’t forget not-persistent rooms in load\_permanent\_rooms - MUC Admin: Better error reporting - MUC Admin: Fix commands with hibernated rooms - MUC Admin: Many improvements in rooms\_unused\_list/destroy - MUC Admin: create\_room\_with\_opts Store options only if room starts - Pubsub: Remove ‘dag’ node plugin documentation - Push: Fix API call return type on error - Push: Support cache config changes on reload - Register: Allow for account-removal-only setup again - Roster: Make roster subscriptions work better with invalid roster state in db - Vcard: Fix vCard search by User when using Mnesia - WebAdmin: Allow vhost admins to view WebAdmin menus - WebAdmin: Don’t do double utf-8 conversion on translated strings - WebAdmin: Mark dangerous buttons with CSS - WebSocket: Make websocket send put back pressure on c2s process ## ejabberd 20.12 download & feedback As usual, the release is tagged in the Git source code repository on [Github](https://github.com/processone/ejabberd.git?ref=process-one.net). The source package and binary installers are available at [ejabberd XMPP & MQTT server download page](https://www.process-one.net/en/ejabberd/downloads/). We’ve discovered some issues with the Windows installer that we are still working on, so its publication is delayed. If you suspect that you’ve found a bug, please search or fill a bug report on [Github](https://github.com/processone/ejabberd/issues?ref=process-one.net). ### Jamler XMPP server, an OCaml experiment based on ejabberd 2.1.8 URL: https://www.process-one.net/blog/jamler-xmpp-server-an-ocaml-experiment-based-on-ejabberd-2-1-8/ Last updated: 2024-09-16T14:44:26.000Z During the [interview with Alexey Shchepin](https://www.process-one.net/blog/interview-with-alexey-shchepin-creator-of-ejabberd/) we had last week, the author of ejabberd mentioned Jamler. Did you notice? [Jamler](https://github.com/processone/jamler/?ref=process-one.net) is an experimental XMPP server, developed mainly in 2011 as an attempt to rewrite ejabberd in OCaml. The goal was to see how static typing would affect ejabberd and its code originally written in Erlang, which has dynamic typing. [OCaml](https://ocaml.org/?ref=process-one.net) is an industrial-strength programming language supporting functional, imperative and object-oriented styles. As ejabberd has evolved a lot since 2011, that’s why you should use [ejabberd 2.1.8](https://www.process-one.net/en/ejabberd/archive/#ejabberd-2.1.8) to compare it to Jamler. In 2020, Jamler has been updated to use the latest versions of OCaml and libraries, but no new features were added. However, we still think it’s valuable to release Jamler as open source. Today, we share with you the [public GitHub repository containing Jamler’s code](https://github.com/processone/jamler/?ref=process-one.net). Containing 630KB of OCaml and 13KB of C, it should be an interesting read to anyone developing real-time solutions in OCaml, or curious about the impact of static typing on code constructs migrated from Erlang. *Photo by* [*Wolfgang Hasselmann*](https://unsplash.com/photos/m4Y6cFwMc10?ref=process-one.net) *on Unsplash* ### Interview with Alexey Shchepin, creator of ejabberd URL: https://www.process-one.net/blog/interview-with-alexey-shchepin-creator-of-ejabberd/ Last updated: 2024-09-16T14:46:34.000Z This month, [ejabberd is 18 years old](https://www.process-one.net/blog/happy-18th-birthday-ejabberd/). On this occasion we talked with Alexey Shchepin, who created ejabberd in November 2002\. Today, ejabberd is one of the most popular XMPP servers in the world, used by millions of people, devices and many big companies like Facebook, WhatsApp, or CCP Games (famous for the EVE Online saga). **Marek: I guess when you created ejabberd, you didn’t expect such growth. When did you realise ejabberd is going to be big?** Alexey: I’m not sure, somewhere between 2003 and 2007\. In 2003 ejabberd could handle jabber.ru load, and in 2007 it was widespread and used in places I didn’t expect. The original goal was to use it to build the global XMPP network, but it was also used as a base for many custom IM solutions. **M: Why did you choose to use Erlang for ejabberd?** A: I found it the most suitable language for implementing an XMPP server. Its support for concurrency and clustering is great. On the other hand, Erlang is pretty slow on many string operations, but they can be implemented in C, so this drawback can be avoided. **M: What do you think about how ejabberd has developed over these 18 years?** A: It has improved a lot in efficiency and flexibility. Although there are a few things which left almost unchanged since the very beginning, lots of internals are completely different now. For example, thanks to Evgeny Khramtov’s work, there is almost no need now to handle XML manually in modules. That was one of the most annoying and boring things. You can write a spec and get packets already parsed into a convenient representation. **M: And can you shed some light on how ProcessOne got involved in ejabberd development?** A: As far as I remember, I was first contacted by Mickaël Rémond in 2004\. He had ideas about commercial applications of ejabberd, which eventually led to ProcessOne supporting ejabberd development. **M: What was the most challenging part in your ejabberd development throughout these 18 years?** A: Probably designing it in the very beginning, as it was my first real program in Erlang. I didn’t know about many things (like gen\_server, supervisors, etc). And the most challenging coding part was implementing the Google Wave module. Its operational transformations were not well-documented, and it took a lot of time to figure everything out. **M: Do you feel any regrets coding that Wave part, seeing how Google shut it all down in the end? Or was some of that code reused in relation to ejabberd later on?** A: Yes, it’s a pity that it was shut, probably it wasn’t convenient or popular enough. Or found its destination as a collaboration feature of Google Docs. Our code wasn’t reused, though it can be revived if an application for it appears. **M: Maybe one day, for an XMPP-based collaboration tool :) Coming back to ejabberd, when you started this XMPP server, it focused on instant messaging, but today it grew much beyond that, especially because it supports other protocols like MQTT and SIP. What in your opinion is the most interesting way to use ejabberd today?** A: I wish I knew that :) For me IM was always the main goal, and it would be great to see major IM providers like Whatsapp or Telegram open a way to federate with 3rd-party servers, but it will probably never happen. **M: You are still an active ejabberd developer. Can you share some of your plans or wishes for the coming years?** A: It’s hard to plan for years ahead. For example, this month Facebook/WhatsApp are going to release a statically-typed variant of Erlang, and maybe it will be so great that we will consider rewriting ejabberd into it. **M: What is your currently favourite desktop and mobile XMPP client? In the early days of ejabberd development you also created the Tkabber client. Any plans on getting back to it?** A: I use Tkabber right now :) No plans on getting back to it – it does what I need from it. And I don’t use any mobile client. **M: I will have to test out Tkabber then. Can you share what are you working on now developing ejabberd? And has the way you use Erlang and develop ejabberd changed over the years?** A: Recently I’ve added JSON encoding/decoding functions generation for XMPP packets. Maybe it’ll help writing lightweight JavaScript clients, as packets will be parsed into JSON objects on the server side. My programming style has become more paranoid I think. Maybe it happens with every growing project – in the beginning you write new code very fast, but then you have to account for more and more things, remember more API calls. And the absence of static typing doesn’t help. **M: That’s true, as the code matures and is used by many, each change has to be careful as to not create problems for the users. The JSON encoding of packets is a really great future and should help web & node developers communicate with ejabberd. Does it have any impact on server performance and throughput?** A: I’ve implemented only proof-of-concept WebSocket module, no benchmarks have been done. But the way JSON packets are encoded and decoded is very similar to XML one, so I hope performance won’t be affected. **M: Excellent. Now for some more general questions: As I understand you have been working remotely for many years now, does that mean the pandemic had little impact on your work? Do you have any advice for developers moving into the fully-remote work?** A: Yes, no impact on my work, and I have no problem sitting at home. On the other hand I have friends who just can’t work from home: it’s either very inconvenient for them, or they can’t concentrate. So I guess there is no universal advice, it just works for some people and don’t for others. Maybe for night owls a solution can be to work at night. **M: What is your Erlang/ejabberd development stack (OS/editor/other tools)?** A: Using Linux since 1999\. For many years my editor had been XEmacs, but now it’s almost not supported by modern Emacs packages, so I switched to Emacs. Other tools are standard like make/git/diff/etc. **M: And which Linux distro do you prefer?** A: Debian. **M: Nice, me too. Are there any other projects you are working on?** A: There was another interesting project implementing ejabberd in OCaml called jamler, but it’s not open-sourced yet. **M: What would be the benefits of implementing ejabberd in OCaml over Erlang?** A: It was an experiment to see how ejabberd would look with static typing. It was written as close as possible to original sources except low-level parts, as they are completely different in OCaml. **M: Would ejabberd code maintenance be easier with OCaml’s static typing, or is it enough to rely on existing Erlang compilation tools to detect problems? Or was the point of this experiment entirely different?** A: Yes, it’s much easier to maintain and refactor when the compiler checks all the typing, or checks that you didn’t miss a branch in your pattern matching. In ejabberd, there are many extra calls to *stringprep* functions, because you can’t just say “accept here only binaries that were stringpreped”. In OCaml you can. **M: Nice, so this would also mean a leaner code. Thank you for the chat! Here’s to the many more years of ejabberd and its continuous development!** To go down the memory lane, you can also check out [this interview with Alexey](https://www.ejabberd.im/interview-aleksey/index.html?ref=process-one.net) conducted in 2005 by Justin Kirby. *Photo by* [*Steve Halama*](https://unsplash.com/photos/NPKk%5F3ZK2DY?ref=process-one.net) *on Unsplash* ### Happy 18th Birthday, ejabberd! URL: https://www.process-one.net/blog/happy-18th-birthday-ejabberd/ Last updated: 2024-09-16T14:48:51.000Z This month marks 18 years of [ejabberd](https://www.process-one.net/en/ejabberd/) development. Alexey Shchepin started ejabberd in November 2002\. Since then it has grown to a super-scalable and rock-solid real-time communication server. ## Universal ejabberd ejabberd supports XMPP, MQTT and SIP protocols. It has many built-in features like a STUN/TURN server, WebSocket & BOSH support, a web admin panel. It’s easy to set up instant messaging, audio and video calling, connected devices and more. ejabberd is a versatile solution with a proven two-decade track record. This means you can be sure your ejabberd deployment will run reliable for years. Together with the [ejabberd community](https://www.ejabberd.im/?ref=process-one.net) we push out regular updates every few months. An ejabberd deployment is easy to keep up-to-date and enjoy the latest features. ## It’s easy with ejabberd Over these 18 years ejabberd became quite easy to use as well. We recently published a series of ejabberd tutorials. You can set up and migrate to your own instance fast & easy following these articles: - [How to move the office to ejabberd XMPP server](https://www.process-one.net/blog/how-to-move-the-office-to-real-time-im-on-ejabberd/) - [How to set up ejabberd video & voice calling (STUN/TURN)](https://www.process-one.net/blog/how-to-set-up-ejabberd-video-voice-calling/) - [How to configure ejabberd to get 100% in XMPP compliance test](https://www.process-one.net/blog/how-to-configure-ejabberd-to-get-100-in-xmpp-compliance-test/) - [Check ejabberd XMPP server useful configuration steps](https://www.process-one.net/blog/ejabberd-xmpp-server-useful-configuration-steps/) - [Starting with MQTT protocol and ejabberd MQTT broker](https://www.process-one.net/blog/starting-with-mqtt-protocol-and-ejabberd-mqtt-broker/) - [Getting started with WebSocket API in ejabberd](https://www.process-one.net/blog/getting-started-with-websocket-api-in-ejabberd/) You can scale your ejabberd to handle millions of connections and users. Through the years, we have supplied the ejabberd docs with many useful articles. And as always, we are here to help you every step of the way: contact us today. Happy 18th Birthday, ejabberd! We wish ejabberd and its fantastic community many more successful years ahead. *Photo by* [*Hannah Busing*](https://unsplash.com/photos/Gl1%5FdJeOtts?ref=process-one.net) *on Unsplash* ### Real-time Radar Issue #40: ProcessOne on Telegram, Fog Computing with XMPP and more URL: https://www.process-one.net/blog/real-time-radar-issue-40-processone-on-telegram-fog-computing-with-xmpp-and-more/ Last updated: 2024-09-16T14:50:57.000Z ### [ProcessOne on Telegram](https://t.me/processone?utm%5Fcampaign=Real-time%20Radar&utm%5Fmedium=email&utm%5Fsource=ProcessOne%20newsletter) You may know that we are quite strict with our social media channels. We only have our official Twitter account, after boycotting Facebook years ago. Today, we would like to invite you to our brand new Telegram channel. Here we will send out announcements and news, and you will be able to comment and discuss with us directly. Join us on Telegram! ### [XMPP Distributed Topology as a Potential Solution for Fog Computing](https://www.semanticscholar.org/paper/XMPP-Distributed-Topology-as-a-Potential-Solution-Numhauser-Mesa/471ca59af7654aeda39e9a680716a77e2eee45e8?utm%5Fcampaign=Real-time%20Radar&utm%5Fmedium=email&utm%5Fsource=ProcessOne%20newsletter) Fog Computing is potentially harmful towards existing Cloud Computing systems as well as Big Data structures. Lack of privacy and potentially unauthorized content distribution are some of many issues to solve. As a possible solution, the authors propose in the following paper the definition of a new Network Topology as well as a working methodology to reduce its impact. ### [Setup XMPP Client To Use Hidden Service](https://creep.im/xmpp%5Ftor/?utm%5Fcampaign=Real-time%20Radar&utm%5Fmedium=email&utm%5Fsource=ProcessOne%20newsletter) If you connect to Creep.im via Tor due to security concerns regarding your location or identity, you may want to use Creep.im’s own hidden service address — creep7nissfumwyx.onion. ### [Hostname Based Proxying with MQTT](https://www.hardill.me.uk/wordpress/2020/10/14/hostname-based-proxying-with-mqtt/?utm%5Fcampaign=Real-time%20Radar&utm%5Fmedium=email&utm%5Fsource=ProcessOne%20newsletter) An interesting question came up on Stack Overflow recently that suggested a hypothetical answer for how to do hostname based proxying for MQTT. In this post the author explores how to actually implement that hypothetical solution. ### [Building a Smart Home Audio Notification System](https://www.element14.com/community/people/aspork42/blog/2020/10/12/building-a-smart-home-audio-notification-system?utm%5Fcampaign=Real-time%20Radar&utm%5Fmedium=email&utm%5Fsource=ProcessOne%20newsletter) Build an audio notification system to tie in to your smart house. This is a “smart speaker” which can intelligently play audio messages notifying if the front door was left open or if the kids leave their room after bedtime. Includes all code, board files, 3D models. ### [Avoid Google’s RCS Text Messaging](https://pocketnow.com/why-you-should-probably-avoid-googles-rcs-text-messaging-chat-feature?utm%5Fcampaign=Real-time%20Radar&utm%5Fmedium=email&utm%5Fsource=ProcessOne%20newsletter) RCS is being promised as the upgrade to text messaging that we’ve been waiting for, but… why can’t we just use the internet for this? ### [Watchcom Uncovers Cisco Jabber Vulnerabilities](https://watchcom.no/nyheter/nyhetsarkiv/uncovers-cisco-jabber-vulnerabilities/?utm%5Fcampaign=Real-time%20Radar&utm%5Fmedium=email&utm%5Fsource=ProcessOne%20newsletter) All vulnerabilities have been responsibly disclosed to Cisco and patches are available. If you or your organization are using Cisco Jabber, update now! ### Getting started with WebSocket API in ejabberd URL: https://www.process-one.net/blog/getting-started-with-websocket-api-in-ejabberd/ Last updated: 2024-09-16T14:53:07.000Z The WebSocket API, as neatly explained by the [MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets%5FAPI?ref=process-one.net), is a technology that makes it possible to open a two-way interactive communication session between the user’s browser and a server. With WebSocket API, you can send messages to a server and receive event-driven responses without having to poll the server for a reply. In a sense it’s similar to XMPP or MQTT, but created with web applications in mind. > **» Don’t want to configure WebSocket API yourself?** > ProcessOne experts will make your business instantly connected. [Contact us »](https://www.process-one.net/en/company/contact) ## ejabberd and WebSocket API WebSocket API listener is present in every latest version of ejabberd installation. If you followed my earlier tutorials, WebSocket API is available on the same port as the admin console, `wss://example.com/5443/ws`. Let’s see what we can do with it. We begin with a [ConverseJS quick start](https://conversejs.org/docs/html/quickstart.html?ref=process-one.net). ConverseJS is a very nice XMPP client for web browsers that supports BOSH and WebSocket API. Our aim is to set up a chat widget on our website, so visitors can instantly chat with us via a predefined login. First, we add ConverseJS resources to the HTML page on which we want to have the chat widget, ideally in the `` section: ```html ``` Then, we add the JavaScript code to initialize ConverseJS. Ideally just before the closing ``: ```html ``` At this point, when we reload our HTML page we should see ConverseJS popup in the lower right corner. However, it asks for user login and doesn’t connect to our ejabberd server. We want an automatic login of a predefined user from our own server, joining a specified chat room. And we want to use WebSocket API instead of BOSH: ``` ``` In order for the above ConverseJS initialiser to work, you need to create a new ejabberd user, for example `www@example.com` with password `pass123`. There are other authentication methods described in the [ConverseJS docs](https://conversejs.org/docs/html/configuration.html?ref=process-one.net#authentication) that enable secure ways to handle `www` user’s password. To make the widget look more like a quick chat window instead of an IM messenger, you can paste the following CSS style right after the `