Run Common Test suite for specific group only [rebar3]"
+ @echo " xref Run cross reference analysis [rebar3]"
+
+#.
+#'
+# vim: foldmarker=#',#. foldmethod=marker:
diff --git a/README.md b/README.md
index 163ead480..646cc4a17 100644
--- a/README.md
+++ b/README.md
@@ -1,208 +1,136 @@
-ejabberd Community Edition
-==========================
-[](https://github.com/processone/ejabberd/actions/workflows/ci.yml)
-[](https://coveralls.io/github/processone/ejabberd?branch=master)
-[](https://hosted.weblate.org/projects/ejabberd/ejabberd-po/)
-[](https://hex.pm/packages/ejabberd)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-ejabberd is a distributed, fault-tolerant technology that allows the creation
-of large-scale instant messaging applications. The server can reliably support
-thousands of simultaneous users on a single node and has been designed to
-provide exceptional standards of fault tolerance. As an open source
-technology, based on industry-standards, ejabberd can be used to build bespoke
-solutions very cost effectively.
+[ejabberd][im] is an open-source,
+robust, scalable and extensible realtime platform built using [Erlang/OTP][erlang],
+that includes [XMPP][xmpp] Server, [MQTT][mqtt] Broker and [SIP][sip] Service.
+Check the features in [ejabberd.im][im], [ejabberd Docs][features],
+[ejabberd at ProcessOne][p1home], and the list of [supported protocols in ProcessOne][xeps]
+and [XMPP.org][xmppej].
-Key Features
+Installation
------------
-- **Cross-platform**
- ejabberd runs under Microsoft Windows and Unix-derived systems such as
- Linux, FreeBSD and NetBSD.
+There are several ways to install ejabberd:
-- **Distributed**
- You can run ejabberd on a cluster of machines and all of them will serve the
- same XMPP domain(s). When you need more capacity you can simply add a new
- cheap node to your cluster. Accordingly, you do not need to buy an expensive
- high-end machine to support tens of thousands concurrent users.
+- Source code: compile yourself, see [COMPILE](COMPILE.md)
+- Installers:
+ - [ProcessOne Download Page][p1download] or [GitHub Releases][releases] for releases.
+ - [GitHub Actions](https://github.com/processone/ejabberd/actions/workflows/installers.yml) for master branch (`run`/`deb`/`rpm` for `x64` and `arm64`)
+- Docker Containers:
+ - `ecs` container image: [Docker Hub][hubecs] and [Github Packages][packagesecs], see [ecs README][docker-ecs-readme] (for `x64`)
+ - `ejabberd` container image: [Github Packages][packages] for releases and master branch, see [CONTAINER](CONTAINER.md) (for `x64` and `arm64`)
+- Using your [Operating System package][osp]
+- Using the [Homebrew][homebrew] package manager
-- **Fault-tolerant**
- You can deploy an ejabberd cluster so that all the information required for
- a properly working service will be replicated permanently on all nodes. This
- means that if one of the nodes crashes, the others will continue working
- without disruption. In addition, nodes also can be added or replaced ‘on
- the fly’.
+More info can be found in the `Installation` part of [ejabberd Docs](https://docs.ejabberd.im/admin/install/).
-- **Administrator-friendly**
- ejabberd is built on top of the Open Source Erlang. As a result you do not
- need to install an external database, an external web server, amongst others
- because everything is already included, and ready to run out of the box.
- Other administrator benefits include:
- - Comprehensive documentation.
- - Straightforward installers for Linux.
- - Docker packaging to help with deploy / development on Linux, Windows or MacOS.
- - Deb and RPM packaging to support most Linux distributions.
- - Web administration.
- - Shared roster groups.
- - Command line administration tool.
- - Can integrate with existing authentication mechanisms.
- - Capability to send announce messages.
+Documentation
+-------------
-- **Internationalized**
- ejabberd leads in internationalization. Hence it is very well suited in a
- globalized world. Related features are:
- - Translated to 25 languages.
- - Support for IDNA.
+Please check the [ejabberd Docs][docs] website.
-- **Open Standards**
- ejabberd is the first Open Source XMPP server claiming to fully comply to
- the XMPP standard.
- - Fully XMPP-compliant.
- - XML-based protocol.
- - Many protocols supported.
-
-
-Additional Features
--------------------
-
-Moreover, ejabberd comes with a wide range of other state-of-the-art features:
-
-- **Modularity**
- - Load only the modules you want.
- - Extend ejabberd with your own custom modules.
-
-- **Security**
- - SASL and STARTTLS for c2s and s2s connections.
- - STARTTLS and Dialback s2s connections.
- - Web Admin accessible via HTTPS secure access.
-
-- **Databases**
- - Internal database for fast deployment (Mnesia).
- - Native MySQL support.
- - Native PostgreSQL support.
- - ODBC data storage support.
- - Microsoft SQL Server support.
-
-- **Authentication**
- - Internal authentication.
- - PAM, LDAP and ODBC.
- - External authentication script.
-
-- **Others**
- - Support for virtual hosting.
- - Compressing XML streams with Stream Compression (XEP-0138).
- - Statistics via Statistics Gathering (XEP-0039).
- - IPv6 support both for c2s and s2s connections.
- - Multi-User Chat module with support for clustering and HTML logging.
- - Users Directory based on users vCards.
- - Publish-Subscribe component with support for Personal Eventing.
- - Support for web clients: HTTP Polling and HTTP Binding (BOSH).
- - Component support: interface with networks such as AIM, ICQ and MSN.
-
-
-Quickstart guide
-----------------
-
-### 0. Requirements
-
-To compile ejabberd you need:
-
- - GNU Make.
- - GCC.
- - Libexpat ≥ 1.95.
- - Libyaml ≥ 0.1.4.
- - Erlang/OTP ≥ 19.3.
- - OpenSSL ≥ 1.0.0.
- - Zlib ≥ 1.2.3, for Stream Compression support (XEP-0138). Optional.
- - PAM library. Optional. For Pluggable Authentication Modules (PAM).
- - ImageMagick's Convert program and Ghostscript fonts. Optional. For CAPTCHA
- challenges.
- - Elixir ≥ 1.10.3. Optional. Alternative to build ejabberd
-
-If your system splits packages in libraries and development headers, you must
-install the development packages also.
-
-### 1. Compile and install on *nix systems
-
-To compile ejabberd, execute the following commands. The first one is only
-necessary if your source tree didn't come with a `configure` script (In this
-case you need autoconf installed).
-
- ./autogen.sh
- ./configure
- make
-
-To install ejabberd, run this command with system administrator rights (root
-user):
-
- sudo make install
-
-These commands will:
-
-- Install the configuration files in `/etc/ejabberd/`
-- Install ejabberd binary, header and runtime files in `/lib/ejabberd/`
-- Install the administration script: `/sbin/ejabberdctl`
-- Install ejabberd documentation in `/share/doc/ejabberd/`
-- Create a spool directory: `/var/lib/ejabberd/`
-- Create a directory for log files: `/var/log/ejabberd/`
-
-
-### 2. Start ejabberd
-
-You can use the `ejabberdctl` command line administration script to
-start and stop ejabberd. For example:
-
- ejabberdctl start
-
-
-For detailed information please refer to the
-[ejabberd Documentation](https://docs.ejabberd.im)
-
-
-### 3. Use ejabberd locally
-
-Alternatively, you can setup ejabberd without installing in your system:
-
- ./configure --with-rebar=rebar3
- make dev
-
-Or, if you have Elixir available and plan to develop Elixir code:
-
- ./configure --with-rebar=mix
- make dev
-
-Check the full list of targets:
+When compiling from source code, you can get some help with:
+ ./configure --help
make help
+Once ejabberd is installed, try:
+
+ ejabberdctl help
+ man ejabberd.yml
Development
-----------
-In order to assist in the development of ejabberd, and particularly the
-execution of the test suite, a Vagrant environment is available at
-https://github.com/processone/ejabberd-vagrant-dev.
+Bug reports and features are tracked using [GitHub Issues][issues],
+please check [CONTRIBUTING](CONTRIBUTING.md) for details.
-To start ejabberd in development mode from the repository directory, you can
-type a command like:
+Translations can be improved online [using Weblate][weblate]
+or in your local machine as explained in [Localization][localization].
- EJABBERD_CONFIG_PATH=ejabberd.yml erl -pa ebin -pa deps/*/ebin -pa test -pa deps/elixir/lib/*/ebin/ -s ejabberd
+Documentation for developers is available in [ejabberd docs: Developers][docs-dev].
+There are nightly builds of ejabberd, both for `master` branch and for Pull Requests:
-Translation
------------
+- Installers: go to [GitHub Actions: Installers](https://github.com/processone/ejabberd/actions/workflows/installers.yml), open the most recent commit, on the bottom of that commit page, download the `ejabberd-packages.zip` artifact.
+- `ejabberd` container image: go to [ejabberd Github Packages][packages]
-Using any gettext editor, you can improve the translation files found in
-`priv/msgs/*.po`, and then submit your changes.
+Security reports or concerns should preferably be reported privately,
+please send an email to the address: contact at process-one dot net
+or some other method from [ProcessOne Contact][p1contact].
-Alternatively, a simple way to improve translations is using our Weblate project:
-https://hosted.weblate.org/projects/ejabberd/ejabberd-po/
+For commercial offering and support, including [ejabberd Business Edition][p1home]
+and [Fluux (ejabberd in the Cloud)][fluux], please check [ProcessOne ejabberd page][p1home].
+Security
+--------
-Links
------
+For information on how to report security vulnerabilities, please refer to the [SECURITY.md](SECURITY.md) file. It contains guidelines on how to report vulnerabilities privately and securely, ensuring that any issues are addressed in a timely and confidential manner.
-- Documentation: https://docs.ejabberd.im
-- Community site: https://www.ejabberd.im
-- ejabberd commercial offering and support: https://www.process-one.net/en/ejabberd
+Community
+---------
+
+There are several places to get in touch with other ejabberd developers and administrators:
+
+- ejabberd XMPP chatroom: [ejabberd@conference.process-one.net][muc]
+- [GitHub Discussions][discussions]
+- [Stack Overflow][stackoverflow]
+
+License
+-------
+
+- ejabberd is released under the __GNU General Public License v2__ (see [COPYING](COPYING))
+- [ejabberd translations](https://github.com/processone/ejabberd-po/) under __MIT License__.
+
+[discussions]: https://github.com/processone/ejabberd/discussions
+[docker-ecs-readme]: https://github.com/processone/docker-ejabberd/tree/master/ecs#readme
+[docs-dev]: https://docs.ejabberd.im/developer/
+[docs]: https://docs.ejabberd.im
+[erlang]: https://www.erlang.org/
+[features]: https://docs.ejabberd.im/admin/introduction/
+[fluux]: https://fluux.io/
+[homebrew]: https://docs.ejabberd.im/admin/install/homebrew/
+[hubecs]: https://hub.docker.com/r/ejabberd/ecs/
+[im]: https://www.ejabberd.im/
+[issues]: https://github.com/processone/ejabberd/issues
+[localization]: https://docs.ejabberd.im/developer/extending-ejabberd/localization/
+[mqtt]: https://mqtt.org/
+[muc]: xmpp:ejabberd@conference.process-one.net
+[osp]: https://docs.ejabberd.im/admin/install/os-package/
+[p1contact]: https://www.process-one.net/contact/
+[p1download]: https://www.process-one.net/download/ejabberd/
+[p1home]: https://www.process-one.net/ejabberd/
+[packages]: https://github.com/processone/ejabberd/pkgs/container/ejabberd
+[packagesecs]: https://github.com/processone/docker-ejabberd/pkgs/container/ecs
+[releases]: https://github.com/processone/ejabberd/releases
+[sip]: https://en.wikipedia.org/wiki/Session_Initiation_Protocol
+[stackoverflow]: https://stackoverflow.com/questions/tagged/ejabberd?sort=newest
+[weblate]: https://hosted.weblate.org/projects/ejabberd/ejabberd-po/
+[xeps]: https://www.process-one.net/ejabberd-features/
+[xmpp]: https://xmpp.org/
+[xmppej]: https://xmpp.org/software/servers/ejabberd/
diff --git a/SECURITY.md b/SECURITY.md
new file mode 100644
index 000000000..bb2292826
--- /dev/null
+++ b/SECURITY.md
@@ -0,0 +1,45 @@
+# Security Policy
+
+## Supported Versions
+
+We recommend that all users always use the latest version of ejabberd.
+
+To ensure the best experience and security, upgrade to the latest version available on [this repo](https://github.com/processone/ejabberd).
+
+## Reporting a Vulnerability
+
+### Private Reporting
+
+**Preferred Method**: Use GitHub's private vulnerability reporting system by clicking the "Report a Vulnerability" button in the [Security tab of this repository](https://github.com/processone/ejabberd/security). This ensures your report is securely transmitted and tracked.
+
+**Alternative**: If you cannot use the GitHub system, send an email to **`contact@process-one.net`** with the following details:
+
+- A clear description of the vulnerability.
+- Steps to reproduce the issue.
+- Any potential impact or exploitation scenarios.
+
+### Response Time
+
+We aim to acknowledge receipt of your report within 72 hours. You can expect regular updates on the status of your report.
+
+### Resolution
+
+If the vulnerability is confirmed, we will work on a patch or mitigation strategy.
+We will notify you once the issue is resolved and coordinate a public disclosure if needed.
+
+### Acknowledgements
+
+We value and appreciate the contributions of security researchers and community members.
+If you wish, we are happy to acknowledge your efforts publicly by listing your name (or alias) below in this document.
+Please let us know if you would like to be recognized when reporting the vulnerability.
+
+## Public Discussion
+
+For general inquiries or discussions about the project’s security, feel free to chat with us here:
+
+- XMPP room: `ejabberd@conference.process-one.net`
+- [GitHub Discussions](https://github.com/processone/ejabberd/discussions)
+
+However, please note that if the issue is **critical** or potentially exploitable, **do not share it publicly**. Instead, we strongly recommend you contact the maintainers directly via the private reporting methods outlined above to ensure a secure and timely response.
+
+Thank you for helping us improve the security of ejabberd!
diff --git a/_checkouts/configure_deps/src/configure_deps_prv.erl b/_checkouts/configure_deps/src/configure_deps_prv.erl
index f4333e4f0..91f2a3adc 100644
--- a/_checkouts/configure_deps/src/configure_deps_prv.erl
+++ b/_checkouts/configure_deps/src/configure_deps_prv.erl
@@ -19,7 +19,7 @@ init(State) ->
{example, "rebar3 configure-deps"}, % How to use the plugin
{opts, []}, % list of options understood by the plugin
{short_desc, "Explicitly run ./configure for dependencies"},
- {desc, "A rebar plugin to allow explicitly running ./configure on depdendencies. Useful if dependencies might change prior to compilation when configure is run."}
+ {desc, "A rebar plugin to allow explicitly running ./configure on dependencies. Useful if dependencies might change prior to compilation when configure is run."}
]),
{ok, rebar_state:add_provider(State, Provider)}.
diff --git a/config/runtime.exs b/config/runtime.exs
index 050eae8b0..adfc18c06 100644
--- a/config/runtime.exs
+++ b/config/runtime.exs
@@ -1,12 +1,15 @@
import Config
-rootpath = System.get_env("RELEASE_ROOT", "")
+rootdefault = case System.get_env("RELIVE", "false") do
+ "true" -> "_build/relive"
+ "false" -> ""
+end
-# This is standard path in the context of ejabberd release
+rootpath = System.get_env("RELEASE_ROOT", rootdefault)
config :ejabberd,
- file: Path.join(rootpath, "etc/ejabberd/ejabberd.yml"),
- log_path: Path.join(rootpath, 'var/log/ejabberd/ejabberd.log')
-
-# Customize Mnesia directory:
+ file: Path.join(rootpath, "conf/ejabberd.yml"),
+ log_path: Path.join(rootpath, "logs/ejabberd.log")
config :mnesia,
- dir: Path.join(rootpath, 'var/lib/ejabberd/')
+ dir: Path.join(rootpath, "database/")
+config :exsync,
+ reload_callback: {:ejabberd_admin, :update, []}
diff --git a/configure.ac b/configure.ac
index 1b0500e0d..b91595dc5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,16 +1,27 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
-AC_PREREQ(2.53)
-AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo 0.0` | sed 's/-g.*//;s/-/./' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd])
-REQUIRE_ERLANG_MIN="8.3 (Erlang/OTP 19.3)"
+AC_PREREQ(2.59)
+AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo 25.08` | sed 's/-g.*//;s/-/./' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd])
+
+AC_ARG_WITH(min-erlang,
+ AS_HELP_STRING([--with-min-erlang=version],[set minimal required erlang version, default to OTP25]),
+[if test "X$withval" = "X"; then
+ REQUIRE_ERLANG_MIN="13.0 (Erlang/OTP 25.0)"
+else
+ REQUIRE_ERLANG_MIN="$withval"
+fi
+], [REQUIRE_ERLANG_MIN="13.0 (Erlang/OTP 25.0)"])
+
REQUIRE_ERLANG_MAX="100.0.0 (No Max)"
AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
AC_PROG_MAKE_SET
+AC_PROG_AWK
AC_PROG_INSTALL
+AC_PROG_MKDIR_P
AC_PROG_SED
if test "x$GCC" = "xyes"; then
@@ -19,8 +30,7 @@ fi
# Checks Erlang runtime and compiler
AC_ARG_WITH(erlang,
- AC_HELP_STRING([--with-erlang=dir],
- [search for erlang in dir]),
+ AS_HELP_STRING([--with-erlang=dir],[search for erlang in dir]),
[if test "$withval" = "yes" -o "$withval" = "no" -o "X$with_erlang" = "X"; then
extra_erl_path=""
else
@@ -29,19 +39,42 @@ fi
])
AC_ARG_WITH(rebar,
- AC_HELP_STRING([--with-rebar=bin],
- [use the rebar/rebar3/mix binary specified]),
+ AS_HELP_STRING([--with-rebar=bin],[use as build tool the rebar/rebar3/mix binary specified]),
[if test "$withval" = "yes" -o "$withval" = "no" -o "X$with_rebar" = "X"; then
- rebar="rebar"
+ rebar="rebar3"
else
rebar="$with_rebar"
fi
-], [rebar="rebar"])
+], [rebar="unconfigured"])
AC_PATH_TOOL(ERL, erl, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(ERLC, erlc, , [${extra_erl_path}$PATH])
AC_PATH_TOOL(EPMD, epmd, , [${extra_erl_path}$PATH])
+AC_PATH_TOOL(REBAR, rebar, , [${extra_erl_path}$PATH])
+AC_PATH_TOOL(REBAR3, rebar3, , [${extra_erl_path}$PATH])
+AC_PATH_TOOL(ELIXIR, elixir, , [${extra_erl_path}$PATH])
+AC_PATH_TOOL(IEX, iex, , [${extra_erl_path}$PATH])
+AC_PATH_TOOL(MIX, mix, , [${extra_erl_path}$PATH])
+
+if test "$rebar" = unconfigured; then
+ if test "x$ELIXIR" = "x" -o "x$IEX" = "x" -o "x$MIX" = "x"; then
+ if test "x$REBAR3" = "x"; then
+ rebar="rebar3"
+ else
+ rebar=$REBAR3
+ fi
+ else
+ rebar=$MIX
+ fi
+fi
+if test "x$rebar" = "xrebar" -a "x$REBAR" = "x" ; then
+ rebar="./rebar"
+fi
+if test "x$rebar" = "xrebar3" -a "x$REBAR3" = "x" ; then
+ rebar="./rebar3"
+fi
+
AC_ERLANG_NEED_ERL
AC_ERLANG_NEED_ERLC
@@ -70,15 +103,15 @@ AC_CONFIG_FILES([Makefile
vars.config])
AC_ARG_ENABLE(all,
-[AC_HELP_STRING([--enable-all], [same as --enable-odbc --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-redis --enable-elixir --enable-stun --enable-sip --enable-debug --enable-lua --enable-tools (useful for Dialyzer checks, default: no)])],
+[AS_HELP_STRING([--enable-all],[same as --enable-odbc --enable-mssql --enable-mysql --enable-pgsql --enable-sqlite --enable-pam --enable-zlib --enable-redis --enable-elixir --enable-stun --enable-sip --enable-debug --enable-lua --enable-tools (useful for Dialyzer checks, default: no)])],
[case "${enableval}" in
- yes) odbc=true mysql=true pgsql=true sqlite=true pam=true zlib=true redis=true elixir=true stun=true sip=true debug=true lua=true tools=true ;;
- no) odbc=false mysql=false pgsql=false sqlite=false pam=false zlib=false redis=false elixir=false stun=false sip=false debug=false lua=false tools=false ;;
+ yes) odbc=true mssql=true mysql=true pgsql=true sqlite=true pam=true zlib=true redis=true elixir=true stun=true sip=true debug=true lua=true tools=true ;;
+ no) odbc=false mssql=false mysql=false pgsql=false sqlite=false pam=false zlib=false redis=false elixir=false stun=false sip=false debug=false lua=false tools=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-all) ;;
esac],[])
AC_ARG_ENABLE(debug,
-[AC_HELP_STRING([--enable-debug], [enable debug information (default: yes)])],
+[AS_HELP_STRING([--enable-debug],[enable debug information (default: yes)])],
[case "${enableval}" in
yes) debug=true ;;
no) debug=false ;;
@@ -86,7 +119,7 @@ AC_ARG_ENABLE(debug,
esac],[if test "x$debug" = "x"; then debug=true; fi])
AC_ARG_ENABLE(elixir,
-[AC_HELP_STRING([--enable-elixir], [enable Elixir support (default: no)])],
+[AS_HELP_STRING([--enable-elixir],[enable Elixir support in Rebar3 (default: no)])],
[case "${enableval}" in
yes) elixir=true ;;
no) elixir=false ;;
@@ -94,8 +127,7 @@ AC_ARG_ENABLE(elixir,
esac],[if test "x$elixir" = "x"; then elixir=false; fi])
AC_ARG_ENABLE(erlang-version-check,
-[AC_HELP_STRING([--enable-erlang-version-check],
- [Check Erlang/OTP version (default: yes)])])
+[AS_HELP_STRING([--enable-erlang-version-check],[Check Erlang/OTP version (default: yes)])])
case "$enable_erlang_version_check" in
yes|'')
ERLANG_VERSION_CHECK([$REQUIRE_ERLANG_MIN],[$REQUIRE_ERLANG_MAX])
@@ -106,7 +138,7 @@ case "$enable_erlang_version_check" in
esac
AC_ARG_ENABLE(full_xml,
-[AC_HELP_STRING([--enable-full-xml], [use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
+[AS_HELP_STRING([--enable-full-xml],[use XML features in XMPP stream (ex: CDATA) (default: no, requires XML compliant clients)])],
[case "${enableval}" in
yes) full_xml=true ;;
no) full_xml=false ;;
@@ -115,7 +147,7 @@ esac],[full_xml=false])
ENABLEGROUP=""
AC_ARG_ENABLE(group,
- [AS_HELP_STRING([--enable-group[[[[=GROUP]]]]], [allow this system group to start ejabberd (default: no)])],
+ [AS_HELP_STRING([--enable-group[[=GROUP]]], [specify the group of the account defined in --enable-user (default: no)])],
[case "${enableval}" in
yes) ENABLEGROUP=`groups |head -n 1` ;;
no) ENABLEGROUP="" ;;
@@ -128,7 +160,7 @@ if test "$ENABLEGROUP" != ""; then
fi
AC_ARG_ENABLE(latest_deps,
-[AC_HELP_STRING([--enable-latest-deps], [makes rebar use latest commits for dependencies instead of tagged versions (default: no)])],
+[AS_HELP_STRING([--enable-latest-deps],[makes rebar use latest commits for dependencies instead of tagged versions (default: no)])],
[case "${enableval}" in
yes) latest_deps=true ;;
no) latest_deps=false ;;
@@ -136,7 +168,7 @@ AC_ARG_ENABLE(latest_deps,
esac],[if test "x$latest_deps" = "x"; then latest_deps=false; fi])
AC_ARG_ENABLE(lua,
-[AC_HELP_STRING([--enable-lua], [enable Lua support, to import from Prosody (default: no)])],
+[AS_HELP_STRING([--enable-lua],[enable Lua support, to import from Prosody (default: no)])],
[case "${enableval}" in
yes) lua=true ;;
no) lua=false ;;
@@ -144,15 +176,15 @@ AC_ARG_ENABLE(lua,
esac],[if test "x$lua" = "x"; then lua=false; fi])
AC_ARG_ENABLE(mssql,
-[AC_HELP_STRING([--enable-mssql], [use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
+[AS_HELP_STRING([--enable-mssql],[use Microsoft SQL Server database (default: no, requires --enable-odbc)])],
[case "${enableval}" in
- yes) db_type=mssql; mssql=true ;;
- no) db_type=generic; mssql=false ;;
+ yes) mssql=true ;;
+ no) mssql=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-mssql) ;;
-esac],[db_type=generic])
+esac],[if test "x$mssql" = "x"; then mssql=false; fi])
AC_ARG_ENABLE(mysql,
-[AC_HELP_STRING([--enable-mysql], [enable MySQL support (default: no)])],
+[AS_HELP_STRING([--enable-mysql],[enable MySQL support (default: no)])],
[case "${enableval}" in
yes) mysql=true ;;
no) mysql=false ;;
@@ -160,7 +192,7 @@ AC_ARG_ENABLE(mysql,
esac],[if test "x$mysql" = "x"; then mysql=false; fi])
AC_ARG_ENABLE(new_sql_schema,
-[AC_HELP_STRING([--enable-new-sql-schema], [use new SQL schema (default: no)])],
+[AS_HELP_STRING([--enable-new-sql-schema],[use new SQL schema by default (default: no)])],
[case "${enableval}" in
yes) new_sql_schema=true ;;
no) new_sql_schema=false ;;
@@ -168,7 +200,7 @@ AC_ARG_ENABLE(new_sql_schema,
esac],[new_sql_schema=false])
AC_ARG_ENABLE(odbc,
-[AC_HELP_STRING([--enable-odbc], [enable pure ODBC support (default: no)])],
+[AS_HELP_STRING([--enable-odbc],[enable pure ODBC support (default: no)])],
[case "${enableval}" in
yes) odbc=true ;;
no) odbc=false ;;
@@ -176,7 +208,7 @@ AC_ARG_ENABLE(odbc,
esac],[if test "x$odbc" = "x"; then odbc=false; fi])
AC_ARG_ENABLE(pam,
-[AC_HELP_STRING([--enable-pam], [enable PAM support (default: no)])],
+[AS_HELP_STRING([--enable-pam],[enable PAM support (default: no)])],
[case "${enableval}" in
yes) pam=true ;;
no) pam=false ;;
@@ -184,7 +216,7 @@ AC_ARG_ENABLE(pam,
esac],[if test "x$pam" = "x"; then pam=false; fi])
AC_ARG_ENABLE(pgsql,
-[AC_HELP_STRING([--enable-pgsql], [enable PostgreSQL support (default: no)])],
+[AS_HELP_STRING([--enable-pgsql],[enable PostgreSQL support (default: no)])],
[case "${enableval}" in
yes) pgsql=true ;;
no) pgsql=false ;;
@@ -192,7 +224,7 @@ AC_ARG_ENABLE(pgsql,
esac],[if test "x$pgsql" = "x"; then pgsql=false; fi])
AC_ARG_ENABLE(redis,
-[AC_HELP_STRING([--enable-redis], [enable Redis support (default: no)])],
+[AS_HELP_STRING([--enable-redis],[enable Redis support (default: no)])],
[case "${enableval}" in
yes) redis=true ;;
no) redis=false ;;
@@ -200,7 +232,7 @@ AC_ARG_ENABLE(redis,
esac],[if test "x$redis" = "x"; then redis=false; fi])
AC_ARG_ENABLE(roster_gateway_workaround,
-[AC_HELP_STRING([--enable-roster-gateway-workaround], [turn on workaround for processing gateway subscriptions (default: no)])],
+[AS_HELP_STRING([--enable-roster-gateway-workaround],[turn on workaround for processing gateway subscriptions (default: no)])],
[case "${enableval}" in
yes) roster_gateway_workaround=true ;;
no) roster_gateway_workaround=false ;;
@@ -208,7 +240,7 @@ AC_ARG_ENABLE(roster_gateway_workaround,
esac],[roster_gateway_workaround=false])
AC_ARG_ENABLE(sip,
-[AC_HELP_STRING([--enable-sip], [enable SIP support (default: no)])],
+[AS_HELP_STRING([--enable-sip],[enable SIP support (default: no)])],
[case "${enableval}" in
yes) sip=true ;;
no) sip=false ;;
@@ -216,7 +248,7 @@ AC_ARG_ENABLE(sip,
esac],[if test "x$sip" = "x"; then sip=false; fi])
AC_ARG_ENABLE(sqlite,
-[AC_HELP_STRING([--enable-sqlite], [enable SQLite support (default: no)])],
+[AS_HELP_STRING([--enable-sqlite],[enable SQLite support (default: no)])],
[case "${enableval}" in
yes) sqlite=true ;;
no) sqlite=false ;;
@@ -224,7 +256,7 @@ AC_ARG_ENABLE(sqlite,
esac],[if test "x$sqlite" = "x"; then sqlite=false; fi])
AC_ARG_ENABLE(stun,
-[AC_HELP_STRING([--enable-stun], [enable STUN/TURN support (default: yes)])],
+[AS_HELP_STRING([--enable-stun],[enable STUN/TURN support (default: yes)])],
[case "${enableval}" in
yes) stun=true ;;
no) stun=false ;;
@@ -232,7 +264,7 @@ AC_ARG_ENABLE(stun,
esac],[if test "x$stun" = "x"; then stun=true; fi])
AC_ARG_ENABLE(system_deps,
-[AC_HELP_STRING([--enable-system-deps], [makes rebar use locally installed dependencies instead of downloading them (default: no)])],
+[AS_HELP_STRING([--enable-system-deps],[makes rebar use locally installed dependencies instead of downloading them (default: no)])],
[case "${enableval}" in
yes) system_deps=true ;;
no) system_deps=false ;;
@@ -240,7 +272,7 @@ AC_ARG_ENABLE(system_deps,
esac],[if test "x$system_deps" = "x"; then system_deps=false; fi])
AC_ARG_ENABLE(tools,
-[AC_HELP_STRING([--enable-tools], [build development tools (default: no)])],
+[AS_HELP_STRING([--enable-tools],[include debugging/development tools (default: no)])],
[case "${enableval}" in
yes) tools=true ;;
no) tools=false ;;
@@ -249,7 +281,7 @@ esac],[if test "x$tools" = "x"; then tools=false; fi])
ENABLEUSER=""
AC_ARG_ENABLE(user,
- [AS_HELP_STRING([--enable-user[[[[=USER]]]]], [allow this system user to start ejabberd (default: no)])],
+ [AS_HELP_STRING([--enable-user[[=USER]]], [allow this system user to start ejabberd (default: no)])],
[case "${enableval}" in
yes) ENABLEUSER=`whoami` ;;
no) ENABLEUSER="" ;;
@@ -262,7 +294,7 @@ if test "$ENABLEUSER" != ""; then
fi
AC_ARG_ENABLE(zlib,
-[AC_HELP_STRING([--enable-zlib], [enable Stream Compression (XEP-0138) using zlib (default: yes)])],
+[AS_HELP_STRING([--enable-zlib],[enable Stream Compression (XEP-0138) using zlib (default: yes)])],
[case "${enableval}" in
yes) zlib=true ;;
no) zlib=false ;;
@@ -283,11 +315,13 @@ case "`uname`" in
;;
esac
+AC_MSG_RESULT([build tool to use (change using --with-rebar): $rebar])
+
AC_SUBST(roster_gateway_workaround)
AC_SUBST(new_sql_schema)
AC_SUBST(full_xml)
-AC_SUBST(db_type)
AC_SUBST(odbc)
+AC_SUBST(mssql)
AC_SUBST(mysql)
AC_SUBST(pgsql)
AC_SUBST(sqlite)
@@ -308,3 +342,28 @@ AC_SUBST(CPPFLAGS)
AC_SUBST(LDFLAGS)
AC_OUTPUT
+
+AS_CASE([$rebar],
+ [*rebar3], [
+ deps=""
+ AS_IF([test "x$stun" = "xfalse"], [deps="stun,$deps"])
+ AS_IF([test "x$sqlite" = "xfalse"], [deps="sqlite3,$deps"])
+ AS_IF([test "x$pgsql" = "xfalse"], [deps="p1_pgsql,$deps"])
+ AS_IF([test "x$mysql" = "xfalse"], [deps="p1_mysql,$deps"])
+ AS_IF([test "x$zlib" = "xfalse"], [deps="ezlib,$deps"])
+ AS_IF([test "x$sip" = "xfalse"], [deps="esip,$deps"])
+ AS_IF([test "x$redis" = "xfalse"], [deps="eredis,$deps"])
+ AS_IF([test "x$pam" = "xfalse"], [deps="epam,$deps"])
+ AS_IF([test "x$deps" = "x"], [],
+ [AC_MSG_NOTICE([unlocking disabled rebar3 dependencies: $deps])
+ $rebar unlock "$deps"])
+ deps=""
+ ERLANG_VERSION=m4_esyscmd([erl -noinput -noshell -eval 'erlang:display(list_to_integer(erlang:system_info(otp_release))), halt().'])
+ AS_IF([test "$ERLANG_VERSION" -lt "21"], [deps="luerl,$deps"])
+ AS_IF([test "$ERLANG_VERSION" -lt "22"], [deps="lager,$deps"])
+ AS_IF([test "$ERLANG_VERSION" -le "23"], [deps="jose,$deps"])
+ AS_IF([test "$ERLANG_VERSION" -ge "27"], [deps="jiffy,$deps"])
+ AS_IF([test "x$deps" = "x"], [],
+ [AC_MSG_NOTICE([unlocking rebar3 dependencies for old Erlang/OTP: $deps])
+ $rebar unlock "$deps"])
+ ])
diff --git a/ejabberd.doap b/ejabberd.doap
new file mode 100644
index 000000000..bfd3f5636
--- /dev/null
+++ b/ejabberd.doap
@@ -0,0 +1,849 @@
+
+
+
+ ejabberd
+ XMPP Server with MQTT Broker and SIP Service
+ Robust, Ubiquitous and Massively Scalable Messaging Platform (XMPP Server, MQTT Broker, SIP Service)
+ 2002-11-16
+ BSD
+ Linux
+ macOS
+ Windows
+ Erlang
+ C
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 2.9
+ 0.5.0
+ complete
+
+
+
+
+
+
+ 2.0
+ 0.5.0
+ complete
+ mod_last
+
+
+
+
+
+ 1.2
+ 16.02
+ complete
+ mod_offline
+
+
+
+
+
+ 1.6
+ 0.5.0
+ complete
+ mod_privacy
+
+
+
+
+
+ 1.4
+ 0.1.0
+ complete
+ mod_offline
+
+
+
+
+
+ 1.3
+ 0.7.5
+ complete
+ mod_offline
+
+
+
+
+
+ 2.4
+ 0.1.0
+ complete
+ mod_disco
+
+
+
+
+
+ 1.1
+ 15.04
+ complete
+ mod_multicast
+
+
+
+
+
+ 0.6.0
+ 0.1.0
+ complete
+ mod_stats
+
+
+
+
+
+ 1.25
+ 0.5.0
+ complete
+ mod_muc
+
+
+
+
+
+ 1.2
+ 0.5.0
+ complete
+ mod_pubsub
+
+
+
+
+
+ 1.2
+ 0.1.0
+ complete
+ mod_private
+
+
+
+
+
+ 1.2
+ 1.1.0
+ complete
+ mod_adhoc
+
+
+
+
+
+ 1.2
+ 0.1.0
+ complete
+ mod_vcard
+
+
+
+
+
+ 1.3
+ 0.1.0
+ complete
+ mod_vcard
+
+
+
+
+
+ 1.0
+ 2.1.0
+ complete
+
+
+
+
+
+
+ 1.14
+ 0.5.0
+ partial
+ mod_pubsub
+
+
+
+
+
+ 1.8
+ 2.0.0
+ complete
+ mod_proxy65
+
+
+
+
+
+ 2.4
+ 0.1.0
+ complete
+ mod_register
+
+
+
+
+
+ 2.5
+ 17.03
+ complete
+ mod_legacy_auth
+
+
+
+
+
+ 1.1.1
+ 2.1.0
+ complete
+
+
+
+
+
+
+ 2.1
+ 2.1.0
+ complete
+ mod_client_state
+
+
+
+
+
+ 1.0
+ 0.5.0
+ complete
+
+
+
+
+
+
+ 1.1
+ 0.1.0
+ complete
+ mod_version
+
+
+
+
+
+ 1.1
+ 0.5.0
+ complete
+
+
+
+
+
+
+ 1.6
+ 0.1.0
+ complete
+ ejabberd_service
+
+
+
+
+
+ 1.5
+ 2.1.4
+ complete
+ mod_caps
+
+
+
+
+
+ 1.11
+ 16.12
+ complete
+ ejabberd_bosh
+
+
+
+
+
+ 1.3.0
+ 13.10
+ partial
+ mod_configure
+
+
+
+
+
+ 2.1
+ 1.1.0
+ complete
+ ejabberd_c2s
+
+
+
+
+
+ 1.1
+ 17.09
+ complete
+ mod_vcard
+
+
+
+
+
+ 1.4.0
+ 22.05
+ complete
+ mod_host_meta
+
+
+
+
+
+ 1.0
+ 2.1.0
+ complete
+ mod_disco
+
+
+
+
+
+ 1.0
+ 2.1.0
+ complete
+ ejabberd_captcha
+
+
+
+
+
+ 1.0
+ 16.01
+ complete
+ mod_offline
+
+
+
+
+
+ 1.2
+ 2.0.0
+ complete
+ mod_pubsub
+
+
+
+
+
+ 1.0
+ 17.12
+ complete
+
+
+
+
+
+
+ 1.2
+ 1.1.0
+ complete
+ ejabberd_auth_anonymous
+
+
+
+
+
+ 1.1
+ 17.03
+ complete
+
+
+
+
+
+
+ 1.0
+ 17.03
+ complete
+ mod_s2s_dialback
+
+
+
+
+
+ 1.2
+ 2.1.7
+ complete
+ mod_blocking
+
+
+
+
+
+ 1.5.2
+ 14.05
+ complete
+ mod_stream_mgmt
+
+
+
+
+
+ 2.0
+ 2.1.0
+ complete
+ mod_ping
+
+
+
+
+
+ 2.0
+ 2.1.0
+ complete
+ mod_time
+
+
+
+
+
+ 2.0
+ 2.1.0
+ complete
+ mod_offline
+
+
+
+
+
+ 1.0
+ 1.1.2
+ complete
+
+
+
+
+
+
+ 1.4
+ 16.12
+ complete
+ ejabberd_bosh
+
+
+
+
+
+ 0.7
+ 20.04
+ complete
+ mod_stun_disco
+
+
+
+
+
+ 1.1.1
+ 17.03
+ complete
+ mod_s2s_dialback
+
+
+
+
+
+ 1.1.1
+ 2.0.0
+ complete
+ mod_pubsub
+
+
+
+
+
+ 1.1
+ 2.1.0
+ partial
+ ejabberd_piefxis
+
+
+
+
+
+ 1.0
+ 2.1.0
+ complete
+ ejabberd_captcha
+
+
+
+
+
+ 1.3
+ 2.1.0
+ complete
+ mod_roster
+
+
+
+
+
+ 0.2
+ 2.1.0
+ complete
+ mod_pubsub
+
+
+
+
+
+ 1.2
+ 0.5.0
+ complete
+ mod_muc
+
+
+
+
+
+ 0.2
+ 2.1.3
+ complete
+ mod_sic
+
+
+
+
+
+ 1.0.1
+ 13.06
+ complete
+ mod_carboncopy
+
+
+
+
+
+ 1.0.1
+ 24.10
+ complete
+ mod_s2s_bidi
+
+
+
+
+
+ 0.6.1
+ 15.06
+ complete
+ mod_mam
+
+
+
+
+
+ 0.3.1
+ 21.12
+ complete
+ mod_muc_room, 0.3.1 since 25.xx
+
+
+
+
+
+ 0.1
+ 19.09
+ complete
+ mod_jidprep
+
+
+
+
+
+ 0.2
+ 16.01
+ complete
+ mod_mam, mod_muc_log, mod_offline
+
+
+
+
+
+ 0.1
+ 14.12
+ complete
+ mod_client_state
+
+
+
+
+
+ 0.4.1
+ 16.09
+ complete
+ mod_delegation
+
+
+
+
+
+ 0.4.1
+ 24.10
+ complete
+ mod_privilege
+
+
+
+
+
+ 0.2
+ 17.08
+ complete
+ mod_push
+
+
+
+
+
+ 0.5.0
+ 15.09
+ complete
+ mod_mam
+
+
+
+
+
+ 0.3.0
+ 15.10
+ complete
+ mod_http_upload
+
+
+
+
+
+ 1.1.0
+ 17.09
+ complete
+
+
+
+
+
+
+ 0.14.1
+ 16.03
+ complete
+ mod_mix
+
+
+
+
+
+ 0.8.3
+ 21.12
+ complete
+ node_pep
+
+
+
+
+
+ 0.3.0
+ 24.02
+ complete
+
+
+
+
+
+
+ 0.4.0
+ 24.02
+ complete
+
+
+
+
+
+
+ 0.2.0
+ 18.03
+ complete
+ mod_avatar
+
+
+
+
+
+ 1.1.3
+ 23.10
+ complete
+ mod_private
+
+
+
+
+
+ 0.3.0
+ 19.02
+ complete
+ mod_mix_pam
+
+
+
+
+
+ 1.1.0
+ 18.12
+ complete
+ mod_muc_room
+
+
+
+
+
+ 0.2.0
+ 18.12
+ complete
+ mod_private
+
+
+
+
+
+ 0.1.0
+ 23.10
+ complete
+ mod_muc_occupantid
+
+
+
+
+
+ 0.4.2
+ 24.02
+ partial
+ mod_mam, Tombstones not implemented
+
+
+
+
+
+ 0.3.0
+ 24.06
+ complete
+ mod_mam
+
+
+
+
+
+ 0.2.0
+ 24.12
+ complete
+ mod_mam
+
+
+
+
+
+ 0.4.0
+ 24.02
+ complete
+
+
+
+
+
+
+ 0.2.0
+ 15.06
+ complete
+ mod_mam
+
+
+
+
+
+ 0.4.0
+ 24.02
+ complete
+ , 0.4.0 since 25.03
+
+
+
+
+
+ 0.2.0
+ 24.10
+ complete
+ mod_scram_upgrade
+
+
+
+
+
+ 0.2.0
+ 24.12
+ complete
+ mod_auth_fast
+
+
+
+
+
+ 0.1.1
+ 25.07
+ complete
+ mod_pubsub_serverinfo
+
+
+
+
+
+ 0.1.0
+ 24.07
+ complete
+ mod_muc
+
+
+
+
diff --git a/ejabberd.service.template b/ejabberd.service.template
index 685a104d0..902a81cb2 100644
--- a/ejabberd.service.template
+++ b/ejabberd.service.template
@@ -9,7 +9,6 @@ Group=@installuser@
LimitNOFILE=65536
Restart=on-failure
RestartSec=5
-WatchdogSec=30
ExecStart=@ctlscriptpath@/ejabberdctl foreground
ExecStop=/bin/sh -c '@ctlscriptpath@/ejabberdctl stop && @ctlscriptpath@/ejabberdctl stopped'
ExecReload=@ctlscriptpath@/ejabberdctl reload_config
diff --git a/ejabberd.yml.example b/ejabberd.yml.example
index 8eb038dd0..b9df7799b 100644
--- a/ejabberd.yml.example
+++ b/ejabberd.yml.example
@@ -36,17 +36,17 @@ listen:
-
port: 5223
ip: "::"
- tls: true
module: ejabberd_c2s
max_stanza_size: 262144
shaper: c2s_shaper
access: c2s
- starttls_required: true
+ tls: true
-
port: 5269
ip: "::"
module: ejabberd_s2s_in
max_stanza_size: 524288
+ shaper: s2s_shaper
-
port: 5443
ip: "::"
@@ -67,7 +67,7 @@ listen:
/admin: ejabberd_web_admin
/.well-known/acme-challenge: ejabberd_acme
-
- port: 3478
+ port: 5478
ip: "::"
transport: udp
module: ejabberd_stun
@@ -111,11 +111,19 @@ access_rules:
api_permissions:
"console commands":
- from:
- - ejabberd_ctl
+ from: ejabberd_ctl
who: all
what: "*"
- "admin access":
+ "webadmin commands":
+ from: ejabberd_web_admin
+ who: admin
+ what: "*"
+ "adhoc commands":
+ from: mod_adhoc_api
+ who: admin
+ what: "*"
+ "http access":
+ from: mod_http_api
who:
access:
allow:
@@ -156,6 +164,7 @@ shaper_rules:
modules:
mod_adhoc: {}
+ mod_adhoc_api: {}
mod_admin_extra: {}
mod_announce:
access: announce
@@ -170,7 +179,7 @@ modules:
mod_fail2ban: {}
mod_http_api: {}
mod_http_upload:
- put_url: https://@HOST@:5443/upload
+ put_url: https://@HOST_URL_ENCODE@:5443/upload
custom_headers:
"Access-Control-Allow-Origin": "https://@HOST@"
"Access-Control-Allow-Methods": "GET,HEAD,PUT,OPTIONS"
@@ -196,6 +205,7 @@ modules:
default_room_options:
mam: true
mod_muc_admin: {}
+ mod_muc_occupantid: {}
mod_offline:
access_max_user_messages: max_user_offline_messages
mod_ping: {}
@@ -224,6 +234,7 @@ modules:
ip_access: trusted_network
mod_roster:
versioning: true
+ mod_s2s_bidi: {}
mod_s2s_dialback: {}
mod_shared_roster: {}
mod_stream_mgmt:
diff --git a/ejabberdctl.cfg.example b/ejabberdctl.cfg.example
index 2300378e0..88f99cd78 100644
--- a/ejabberdctl.cfg.example
+++ b/ejabberdctl.cfg.example
@@ -47,10 +47,28 @@
#INET_DIST_INTERFACE=127.0.0.1
#.
-#' ERL_EPMD_ADDRESS: IP addresses where epmd listens for connections
+#' ERL_DIST_PORT: Port number for Erlang distribution
+#
+# For Erlang distribution, clustering and ejabberdctl usage, the
+# Erlang VM listens in a random TCP port number, and the Erlang Port
+# Mapper Daemon (EPMD) is spawned and used to determine this port
+# number.
+#
+# ERL_DIST_PORT can define this port number. In that case, EPMD is
+# not spawned during ejabberd startup, and ERL_EPMD_ADDRESS is
+# ignored. ERL_DIST_PORT must be set to the same port number during
+# ejabberd startup and when calling ejabberdctl. This feature
+# requires at least Erlang/OTP 23.1.
+#
+# Default: not defined
+#
+#ERL_DIST_PORT=5210
+
+#.
+#' ERL_EPMD_ADDRESS: IP addresses where EPMD listens for connections
#
# This environment variable may be set to a comma-separated
-# list of IP addresses, in which case the epmd daemon
+# list of IP addresses, in which case the EPMD daemon
# will listen only on the specified address(es) and on the
# loopback address (which is implicitly added to the list if it
# has not been specified). The default behaviour is to listen on
@@ -90,10 +108,11 @@
#.
#' ERL_OPTIONS: Additional Erlang options
#
-# The next variable allows to specify additional options passed to erlang while
-# starting ejabberd. Some useful options are -noshell, -detached, -heart. When
-# ejabberd is started from an init.d script options -noshell and -detached are
-# added implicitly. See erl(1) for more info.
+# The next variable allows to specify additional options passed to
+# all commands using erlang interpreter. This applies to starting
+# ejabberd server itself but also auxiliary commands like for example
+# starting debug shell. See erl(1) for list of commands that can be
+# used here.
#
# It might be useful to add "-pa /usr/local/lib/ejabberd/ebin" if you
# want to add local modules in this path.
@@ -102,6 +121,20 @@
#
#ERL_OPTIONS=""
+#.
+#' EJABBERD_OPTS: Additional Erlang options to start ejabberd
+#
+# The next variable allows to specify additional options passed to erlang while
+# starting ejabberd. Some useful options are -noshell, -detached, -heart. When
+# ejabberd is started from an init.d script options -noshell and -detached are
+# added implicitly. See erl(1) for more info.
+#
+# For example you can use value "-heart -env HEART_BEAT_TIMEOUT 120 -env ERL_CRASH_DUMP_SECONDS 60"
+#
+# Default: ""
+#
+#EJABBERD_OPTS=""
+
#.
#' ERLANG_NODE: Erlang node name
#
@@ -165,6 +198,17 @@
#
#CONTRIB_MODULES_CONF_DIR=/etc/ejabberd/modules
+#.
+#' CTL_OVER_HTTP: Path to ejabberdctl HTTP listener socket
+#
+# To speedup ejabberdctl execution time for ejabberd commands,
+# you can setup an ejabberd_http listener with ejabberd_ctl handling requests,
+# listening in a unix domain socket.
+#
+# Default: disabled
+#
+#CTL_OVER_HTTP=sockets/ctl_over_http.sock
+
#.
#'
# vim: foldmarker=#',#. foldmethod=marker:
diff --git a/ejabberdctl.template b/ejabberdctl.template
index 4cab19977..0d124bead 100755
--- a/ejabberdctl.template
+++ b/ejabberdctl.template
@@ -12,9 +12,11 @@ ERLANG_NODE=ejabberd@localhost
# define default environment variables
[ -z "$SCRIPT" ] && SCRIPT=$0
SCRIPT_DIR="$(cd "$(dirname "$SCRIPT")" && pwd -P)"
+# shellcheck disable=SC2034
+ERTS_VSN="{{erts_vsn}}"
ERL="{{erl}}"
-IEX="{{bindir}}/iex"
EPMD="{{epmd}}"
+IEX="{{iexpath}}"
INSTALLUSER="{{installuser}}"
# check the proper system user is used
@@ -48,69 +50,87 @@ while [ $# -gt 0 ]; do
-l|--logs) LOGS_DIR=$2; shift 2;;
-f|--config) EJABBERD_CONFIG_PATH=$2; shift 2;;
-c|--ctl-config) EJABBERDCTL_CONFIG_PATH=$2; shift 2;;
- -d|--config-dir) ETC_DIR=$2; shift 2;;
+ -d|--config-dir) CONFIG_DIR=$2; shift 2;;
-t|--no-timeout) NO_TIMEOUT="--no-timeout"; shift;;
*) break;;
esac
done
# define ejabberd variables if not already defined from the command line
-: "${ETC_DIR:="{{sysconfdir}}/ejabberd"}"
-: "${LOGS_DIR:="{{localstatedir}}/log/ejabberd"}"
-: "${SPOOL_DIR:="{{localstatedir}}/lib/ejabberd"}"
-: "${EJABBERD_CONFIG_PATH:="$ETC_DIR/ejabberd.yml"}"
-: "${EJABBERDCTL_CONFIG_PATH:="$ETC_DIR/ejabberdctl.cfg"}"
+: "${CONFIG_DIR:="{{config_dir}}"}"
+: "${LOGS_DIR:="{{logs_dir}}"}"
+: "${EJABBERD_CONFIG_PATH:="$CONFIG_DIR/ejabberd.yml"}"
+: "${EJABBERDCTL_CONFIG_PATH:="$CONFIG_DIR/ejabberdctl.cfg"}"
# Allows passing extra Erlang command-line arguments in vm.args file
-: "${VMARGS:="$ETC_DIR/vm.args"}"
+: "${VMARGS:="$CONFIG_DIR/vm.args"}"
+# shellcheck source=ejabberdctl.cfg.example
[ -f "$EJABBERDCTL_CONFIG_PATH" ] && . "$EJABBERDCTL_CONFIG_PATH"
[ -n "$ERLANG_NODE_ARG" ] && ERLANG_NODE="$ERLANG_NODE_ARG"
+[ "$ERLANG_NODE" = "${ERLANG_NODE%@*}" ] && ERLANG_NODE="$ERLANG_NODE@$(hostname -s)"
[ "$ERLANG_NODE" = "${ERLANG_NODE%.*}" ] && S="-s"
-: "${EJABBERD_DOC_PATH:="{{docdir}}"}"
+: "${SPOOL_DIR:="{{spool_dir}}"}"
: "${EJABBERD_LOG_PATH:="$LOGS_DIR/ejabberd.log"}"
+# backward support for old mnesia spool dir path
+: "${SPOOL_DIR_OLD:="$SPOOL_DIR/$ERLANG_NODE"}"
+[ -r "$SPOOL_DIR_OLD/schema.DAT" ] && [ ! -r "$SPOOL_DIR/schema.DAT" ] && SPOOL_DIR="$SPOOL_DIR_OLD"
+
# define erl parameters
ERLANG_OPTS="+K $POLL +P $ERL_PROCESSES $ERL_OPTIONS"
if [ -n "$FIREWALL_WINDOW" ] ; then
ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_listen_min ${FIREWALL_WINDOW%-*} inet_dist_listen_max ${FIREWALL_WINDOW#*-}"
fi
if [ -n "$INET_DIST_INTERFACE" ] ; then
- INET_DIST_INTERFACE2=$("$ERL" -noshell -eval 'case inet:parse_address("'$INET_DIST_INTERFACE'") of {ok,IP} -> io:format("~p",[IP]); _ -> ok end.' -s erlang halt)
+ INET_DIST_INTERFACE2=$("$ERL" $ERLANG_OPTS -noshell -eval 'case inet:parse_address("'$INET_DIST_INTERFACE'") of {ok,IP} -> io:format("~p",[IP]); _ -> ok end.' -s erlang halt)
if [ -n "$INET_DIST_INTERFACE2" ] ; then
+ if [ "$(echo "$INET_DIST_INTERFACE2" | grep -o "," | wc -l)" -eq 7 ] ; then
+ INET_DIST_INTERFACE2="$INET_DIST_INTERFACE2 -proto_dist inet6_tcp"
+ fi
ERLANG_OPTS="$ERLANG_OPTS -kernel inet_dist_use_interface $INET_DIST_INTERFACE2"
fi
fi
+[ -n "$ERL_DIST_PORT" ] && ERLANG_OPTS="$ERLANG_OPTS -erl_epmd_port $ERL_DIST_PORT -start_epmd false"
# if vm.args file exists in config directory, pass it to Erlang VM
[ -f "$VMARGS" ] && ERLANG_OPTS="$ERLANG_OPTS -args_file $VMARGS"
-ERL_LIBS={{libdir}}
+ERL_LIBS='{{libdir}}'
ERL_CRASH_DUMP="$LOGS_DIR"/erl_crash_$(date "+%Y%m%d-%H%M%S").dump
-ERL_INETRC="$ETC_DIR"/inetrc
+ERL_INETRC="$CONFIG_DIR"/inetrc
# define ejabberd parameters
-EJABBERD_OPTS="$EJABBERD_OPTS\
-$(sed '/^log_rotate_size/!d;s/:[ \t]*\([0-9]\{1,\}\).*/ \1/;s/:[ \t]*\(infinity\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")\
-$(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1/;s/^/ /' "$EJABBERD_CONFIG_PATH")"
+EJABBERD_OPTS="\
+$(sed '/^log_rotate_size/!d;s/:[ \t]*\([0-9]\{1,\}\).*/ \1/;s/:[ \t]*\(infinity\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
+$(sed '/^log_rotate_count/!d;s/:[ \t]*\([0-9]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
+$(sed '/^log_burst_limit_count/!d;s/:[ \t]*\([0-9]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
+$(sed '/^log_burst_limit_window_time/!d;s/:[ \t]*\([0-9]*[a-z]*\).*/ \1 /;s/^/ /' "$EJABBERD_CONFIG_PATH")\
+$EJABBERD_OPTS"
[ -n "$EJABBERD_OPTS" ] && EJABBERD_OPTS="-ejabberd $EJABBERD_OPTS"
EJABBERD_OPTS="-mnesia dir \"$SPOOL_DIR\" $MNESIA_OPTIONS $EJABBERD_OPTS -s ejabberd"
# export global variables
export EJABBERD_CONFIG_PATH
export EJABBERD_LOG_PATH
-export EJABBERD_DOC_PATH
export EJABBERD_PID_PATH
export ERL_CRASH_DUMP
export ERL_EPMD_ADDRESS
+export ERL_DIST_PORT
export ERL_INETRC
export ERL_MAX_PORTS
export ERL_MAX_ETS_TABLES
export CONTRIB_MODULES_PATH
export CONTRIB_MODULES_CONF_DIR
export ERL_LIBS
+export SCRIPT_DIR
+
+set_dist_client()
+{
+ [ -n "$ERL_DIST_PORT" ] && ERLANG_OPTS="$ERLANG_OPTS -dist_listen false"
+}
# run command either directly or via su $INSTALLUSER
exec_cmd()
{
case $EXEC_CMD in
- as_install_user) su -s /bin/sh -c '"$0" "$@"' "$INSTALLUSER" -- "$@" ;;
+ as_install_user) su -s /bin/sh -c 'exec "$0" "$@"' "$INSTALLUSER" -- "$@" ;;
as_current_user) "$@" ;;
esac
}
@@ -128,14 +148,6 @@ exec_iex()
# usage
debugwarning()
{
- if [ "$OSTYPE" != "cygwin" ] && [ "$OSTYPE" != "win32" ] ; then
- if [ "a$TERM" = "a" ] || [ "$TERM" = "dumb" ] ; then
- echo "Terminal type not supported."
- echo "You may have to set the TERM environment variable to fix this."
- exit 8
- fi
- fi
-
if [ "$EJABBERD_BYPASS_WARNINGS" != "true" ] ; then
echo "--------------------------------------------------------------------"
echo ""
@@ -146,14 +158,16 @@ debugwarning()
echo "Please be extremely cautious with your actions,"
echo "and exit immediately if you are not completely sure."
echo ""
- echo "To detach this shell from ejabberd, press:"
- echo " control+c, control+c"
+ echo "To exit and detach this shell from ejabberd, press:"
+ echo " control+g and then q"
echo ""
+ #vt100 echo "Please do NOT use control+c in this debug shell !"
+ #vt100 echo ""
echo "--------------------------------------------------------------------"
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press return to continue"
- read -r input
+ read -r _
echo ""
fi
}
@@ -169,31 +183,72 @@ livewarning()
echo "Please be extremely cautious with your actions,"
echo "and exit immediately if you are not completely sure."
echo ""
- echo "To exit this LIVE mode and stop ejabberd, press:"
- echo " q(). and press the Enter key"
+ echo "To stop ejabberd gracefully:"
+ echo " ejabberd:stop()."
+ echo "To quit erlang immediately, press:"
+ echo " control+g and then q"
echo ""
echo "--------------------------------------------------------------------"
echo "To bypass permanently this warning, add to ejabberdctl.cfg the line:"
echo " EJABBERD_BYPASS_WARNINGS=true"
echo "Press return to continue"
- read -r input
+ read -r _
echo ""
fi
}
+check_etop_result()
+{
+ result=$?
+ if [ $result -eq 1 ] ; then
+ echo ""
+ echo "It seems there was some problem running 'ejabberdctl etop'."
+ echo "Is the error message something like this?"
+ echo " Failed to load module 'etop' because it cannot be found..."
+ echo "Then probably ejabberd was compiled with development tools disabled."
+ echo "To use 'etop', recompile ejabberd with: ./configure --enable-tools"
+ echo ""
+ exit $result
+ fi
+}
+
+check_iex_result()
+{
+ result=$?
+ if [ $result -eq 127 ] ; then
+ echo ""
+ echo "It seems there was some problem finding 'iex' binary from Elixir."
+ echo "Probably ejabberd was compiled with Rebar3 and Elixir disabled, like:"
+ echo " ./configure"
+ echo "which is equivalent to:"
+ echo " ./configure --with-rebar=rebar3 --disable-elixir"
+ echo "To use 'iex', recompile ejabberd enabling Elixir or using Mix:"
+ echo " ./configure --enable-elixir"
+ echo " ./configure --with-rebar=mix"
+ echo ""
+ exit $result
+ fi
+}
+
help()
{
echo ""
echo "Commands to start an ejabberd node:"
- echo " start Start an ejabberd node in server mode"
- echo " debug Attach an interactive Erlang shell to a running ejabberd node"
- echo " iexdebug Attach an interactive Elixir shell to a running ejabberd node"
- echo " live Start an ejabberd node in live (interactive) mode"
- echo " iexlive Start an ejabberd node in live (interactive) mode, within an Elixir shell"
- echo " foreground Start an ejabberd node in server mode (attached)"
+ echo " start Start in server mode"
+ echo " foreground Start in server mode (attached)"
+ echo " foreground-quiet Start in server mode (attached), show only critical messages"
+ echo " live Start in interactive mode, with Erlang shell"
+ echo " iexlive Start in interactive mode, with Elixir shell"
+ echo ""
+ echo "Commands to interact with a running ejabberd node:"
+ echo " debug Attach an interactive Erlang shell to a running node"
+ echo " iexdebug Attach an interactive Elixir shell to a running node"
+ echo " etop Attach to a running node and start Erlang Top"
+ echo " ping Send ping to the node, returns pong or pang"
+ echo " started|stopped Wait for the node to fully start|stop"
echo ""
echo "Optional parameters when starting an ejabberd node:"
- echo " --config-dir dir Config ejabberd: $ETC_DIR"
+ echo " --config-dir dir Config ejabberd: $CONFIG_DIR"
echo " --config file Config ejabberd: $EJABBERD_CONFIG_PATH"
echo " --ctl-config file Config ejabberdctl: $EJABBERDCTL_CONFIG_PATH"
echo " --logs dir Directory for logs: $LOGS_DIR"
@@ -203,20 +258,40 @@ help()
}
# dynamic node name helper
-uid()
-{
- uuid=$(uuidgen 2>/dev/null)
- [ -z "$uuid" ] && [ -f /proc/sys/kernel/random/uuid ] && uuid=$(cat /proc/sys/kernel/random/uuid)
- [ -z "$uuid" ] && uuid=$(printf "%X" "${RANDOM:-$$}$(date +%M%S)")
- uuid=$(printf '%s' $uuid | sed 's/^\(...\).*$/\1/')
- [ $# -eq 0 ] && echo "${uuid}-${ERLANG_NODE}"
- [ $# -eq 1 ] && echo "${uuid}-${1}-${ERLANG_NODE}"
- [ $# -eq 2 ] && echo "${uuid}-${1}@${2}"
+uid() {
+ ERTSVERSION="$("$ERL" -version 2>&1 | sed 's|.* \([0-9]*[0-9]\).*|\1|g')"
+ if [ $ERTSVERSION -lt 11 ] ; then # otp 23.0 includes erts 11.0
+ # Erlang/OTP lower than 23, which doesn's support dynamic node code
+ N=1
+ PF=$(( $$ % 97 ))
+ while
+ case $# in
+ 0) NN="${PF}-${N}-${ERLANG_NODE}"
+ ;;
+ 1) NN="${PF}-${N}-${1}-${ERLANG_NODE}"
+ ;;
+ 2) NN="${PF}-${N}-${1}@${2}"
+ ;;
+ esac
+ N=$(( N + 1 + ( $$ % 5 ) ))
+ "$EPMD" -names 2>/dev/null | grep -q " ${NN%@*} "
+ do :; done
+ echo $NN
+ else
+ # Erlang/OTP 23 or higher: use native dynamic node code
+ # https://www.erlang.org/patches/otp-23.0#OTP-13812
+ if [ "$ERLANG_NODE" != "${ERLANG_NODE%.*}" ]; then
+ echo "undefined@${ERLANG_NODE#*@}"
+ else
+ echo "undefined"
+ fi
+ fi
}
# stop epmd if there is no other running node
stop_epmd()
{
+ [ -n "$ERL_DIST_PORT" ] && return
"$EPMD" -names 2>/dev/null | grep -q name || "$EPMD" -kill >/dev/null
}
@@ -224,6 +299,7 @@ stop_epmd()
# if all ok, ensure runtime directory exists and make it current directory
check_start()
{
+ [ -n "$ERL_DIST_PORT" ] && return
"$EPMD" -names 2>/dev/null | grep -q " ${ERLANG_NODE%@*} " && {
pgrep -f "$ERLANG_NODE" >/dev/null && {
echo "ERROR: The ejabberd node '$ERLANG_NODE' is already running."
@@ -242,6 +318,13 @@ check_start()
# allow sync calls
wait_status()
{
+ wait_status_node "$ERLANG_NODE" $1 $2 $3
+}
+
+wait_status_node()
+{
+ CONNECT_NODE=$1
+ shift
# args: status try delay
# return: 0 OK, 1 KO
timeout="$2"
@@ -252,14 +335,71 @@ wait_status()
if [ $timeout -eq 0 ] ; then
status="$1"
else
- exec_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl \
- -extra "$ERLANG_NODE" $NO_TIMEOUT status > /dev/null
+ exec_erl "$(uid ctl)" -hidden -noinput \
+ -eval 'net_kernel:connect_node('"'$CONNECT_NODE'"')' \
+ -s ejabberd_ctl \
+ -extra "$CONNECT_NODE" $NO_TIMEOUT status > /dev/null
status="$?"
fi
done
[ $timeout -gt 0 ]
}
+exec_other_command()
+{
+ exec_other_command_node $ERLANG_NODE "$@"
+}
+
+exec_other_command_node()
+{
+ CONNECT_NODE=$1
+ shift
+ if [ -z "$CTL_OVER_HTTP" ] || [ ! -S "$CTL_OVER_HTTP" ] \
+ || [ ! -x "$(command -v curl)" ] || [ -z "$1" ] || [ "$1" = "help" ] \
+ || [ "$1" = "mnesia_info_ctl" ]|| [ "$1" = "print_sql_schema" ] ; then
+ exec_erl "$(uid ctl)" -hidden -noinput \
+ -eval 'net_kernel:connect_node('"'$CONNECT_NODE'"')' \
+ -s ejabberd_ctl \
+ -extra "$CONNECT_NODE" $NO_TIMEOUT "$@"
+ result=$?
+ case $result in
+ 3) help;;
+ *) :;;
+ esac
+ return $result
+ else
+ exec_ctl_over_http_socket "$@"
+ fi
+}
+
+exec_ctl_over_http_socket()
+{
+ COMMAND=${1}
+ CARGS=""
+ while [ $# -gt 0 ]; do
+ [ -z "$CARGS" ] && CARGS="[" || CARGS="${CARGS}, "
+ CARGS="${CARGS}\"$1\""
+ shift
+ done
+ CARGS="${CARGS}]"
+ TEMPHEADERS=temp-headers.log
+ curl \
+ --unix-socket ${CTL_OVER_HTTP} \
+ --header "Content-Type: application/json" \
+ --header "Accept: application/json" \
+ --data "${CARGS}" \
+ --dump-header ${TEMPHEADERS} \
+ --no-progress-meter \
+ "http://localhost/ctl/${COMMAND}"
+ result=$(sed -n 's/.*status-code: \([0-9]*\).*/\1/p' < $TEMPHEADERS)
+ rm ${TEMPHEADERS}
+ case $result in
+ 2|3) exec_other_command help ${COMMAND};;
+ *) :;;
+ esac
+ exit $result
+}
+
# ensure we can change current directory to SPOOL_DIR
[ -d "$SPOOL_DIR" ] || exec_cmd mkdir -p "$SPOOL_DIR"
cd "$SPOOL_DIR" || {
@@ -267,6 +407,103 @@ cd "$SPOOL_DIR" || {
exit 6
}
+printe()
+{
+ printf "\n"
+ printf "\e[1;40;32m==> %s\e[0m\n" "$1"
+}
+
+## Function copied from tools/make-installers
+user_agrees()
+{
+ question="$*"
+
+ if [ -t 0 ]
+ then
+ printe "$question (y/n) [n]"
+ read -r response
+ case "$response" in
+ [Yy]|[Yy][Ee][Ss])
+ return 0
+ ;;
+ [Nn]|[Nn][Oo]|'')
+ return 1
+ ;;
+ *)
+ echo 'Please respond with "yes" or "no".'
+ user_agrees "$question"
+ ;;
+ esac
+ else # Assume 'yes' if not running interactively.
+ return 0
+ fi
+}
+
+mnesia_change()
+{
+ ERLANG_NODE_OLD="$1"
+ [ "$ERLANG_NODE_OLD" = "" ] \
+ && echo "Error: Please provide the old erlang node name, for example:" \
+ && echo " ejabberdctl mnesia_change ejabberd@oldmachine" \
+ && exit 1
+
+ SPOOL_DIR_BACKUP=$SPOOL_DIR/$ERLANG_NODE_OLD-backup/
+ OLDFILE=$SPOOL_DIR_BACKUP/$ERLANG_NODE_OLD.backup
+ NEWFILE=$SPOOL_DIR_BACKUP/$ERLANG_NODE.backup
+
+ printe "This changes your mnesia database from node name '$ERLANG_NODE_OLD' to '$ERLANG_NODE'"
+
+ [ -d "$SPOOL_DIR_BACKUP" ] && printe "WARNING! A backup of old node already exists in $SPOOL_DIR_BACKUP"
+
+ if ! user_agrees "Do you want to proceed?"
+ then
+ echo 'Operation aborted.'
+ exit 1
+ fi
+
+ printe "Starting ejabberd with old node name $ERLANG_NODE_OLD ..."
+ exec_erl "$ERLANG_NODE_OLD" $EJABBERD_OPTS -detached
+ wait_status_node $ERLANG_NODE_OLD 0 30 2
+ result=$?
+ case $result in
+ 1) echo "There was a problem starting ejabberd with the old erlang node name. " \
+ && echo "Check for log errors in $EJABBERD_LOG_PATH" \
+ && exit $result;;
+ *) :;;
+ esac
+ exec_other_command_node $ERLANG_NODE_OLD "status"
+
+ printe "Making backup of old database to file $OLDFILE ..."
+ mkdir $SPOOL_DIR_BACKUP
+ exec_other_command_node $ERLANG_NODE_OLD backup "$OLDFILE"
+
+ printe "Changing node name in new backup file $NEWFILE ..."
+ exec_other_command_node $ERLANG_NODE_OLD mnesia_change_nodename "$ERLANG_NODE_OLD" "$ERLANG_NODE" "$OLDFILE" "$NEWFILE"
+
+ printe "Stopping old ejabberd..."
+ exec_other_command_node $ERLANG_NODE_OLD "stop"
+ wait_status_node $ERLANG_NODE_OLD 3 30 2 && stop_epmd
+
+ printe "Moving old mnesia spool files to backup subdirectory $SPOOL_DIR_BACKUP ..."
+ mv $SPOOL_DIR/*.DAT $SPOOL_DIR_BACKUP
+ mv $SPOOL_DIR/*.DCD $SPOOL_DIR_BACKUP
+ mv $SPOOL_DIR/*.LOG $SPOOL_DIR_BACKUP
+
+ printe "Starting ejabberd with new node name $ERLANG_NODE ..."
+ exec_erl "$ERLANG_NODE" $EJABBERD_OPTS -detached
+ wait_status 0 30 2
+ exec_other_command "status"
+
+ printe "Installing fallback of new mnesia..."
+ exec_other_command install_fallback "$NEWFILE"
+
+ printe "Stopping new ejabberd..."
+ exec_other_command "stop"
+ wait_status 3 30 2 && stop_epmd
+
+ printe "Finished, now you can start ejabberd normally"
+}
+
# main
case $1 in
start)
@@ -288,41 +525,50 @@ case $1 in
;;
debug)
debugwarning
+ set_dist_client
exec_erl "$(uid debug)" -hidden -remsh "$ERLANG_NODE"
;;
etop)
- exec_erl "$(uid top)" -hidden -node "$ERLANG_NODE" -s etop \
- -s erlang halt -output text
+ set_dist_client
+ exec_erl "$(uid top)" -hidden -remsh "$ERLANG_NODE" -s etop \
+ -output text
+ check_etop_result
;;
iexdebug)
debugwarning
+ set_dist_client
exec_iex "$(uid debug)" --remsh "$ERLANG_NODE"
+ check_iex_result
;;
iexlive)
livewarning
- exec_iex "$ERLANG_NODE" --erl "$EJABBERD_OPTS" --app ejabberd
+ exec_iex "$ERLANG_NODE" --erl "$EJABBERD_OPTS"
+ check_iex_result
;;
ping)
PEER=${2:-$ERLANG_NODE}
[ "$PEER" = "${PEER%.*}" ] && PS="-s"
+ set_dist_client
exec_cmd "$ERL" ${PS:--}name "$(uid ping "$(hostname $PS)")" $ERLANG_OPTS \
- -noinput -hidden -eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \
- -s erlang halt -output text
+ -noinput -hidden \
+ -eval 'net_kernel:connect_node('"'$PEER'"')' \
+ -eval 'io:format("~p~n",[net_adm:ping('"'$PEER'"')])' \
+ -eval 'halt(case net_adm:ping('"'$PEER'"') of pong -> 0; pang -> 1 end).' \
+ -output text
;;
started)
+ set_dist_client
wait_status 0 30 2 # wait 30x2s before timeout
;;
stopped)
+ set_dist_client
wait_status 3 30 2 && stop_epmd # wait 30x2s before timeout
;;
+ mnesia_change)
+ mnesia_change $2
+ ;;
*)
- exec_erl "$(uid ctl)" -hidden -noinput -s ejabberd_ctl \
- -extra "$ERLANG_NODE" $NO_TIMEOUT "$@"
- result=$?
- case $result in
- 2|3) help;;
- *) :;;
- esac
- exit $result
+ set_dist_client
+ exec_other_command "$@"
;;
esac
diff --git a/elvis.config b/elvis.config
new file mode 100644
index 000000000..4ac4df9e1
--- /dev/null
+++ b/elvis.config
@@ -0,0 +1,59 @@
+[
+ {
+ elvis,
+ [
+ {config,
+ [#{dirs => ["src"],
+ filter => "*.erl",
+ ignore => ['ELDAPv3', eldap_filter_yecc],
+ ruleset => erl_files,
+ rules => [{elvis_text_style, line_length, #{limit => 1000, skip_comments => false}},
+ {elvis_text_style, no_tabs, disable},
+ {elvis_style, atom_naming_convention, disable},
+ {elvis_style, consistent_variable_casing, disable},
+ {elvis_style, dont_repeat_yourself, #{min_complexity => 70}},
+ {elvis_style, export_used_types, disable},
+ {elvis_style, function_naming_convention, disable},
+ {elvis_style, god_modules, #{limit => 300}},
+ {elvis_style, invalid_dynamic_call, disable},
+ {elvis_style, macro_names, disable},
+ {elvis_style, max_function_arity, disable}, % #{max_arity => 15}},
+ {elvis_style, nesting_level, disable},
+ {elvis_style, no_author, disable},
+ {elvis_style, no_boolean_in_comparison, disable},
+ {elvis_style, no_catch_expressions, disable},
+ {elvis_style, no_debug_call, disable},
+ {elvis_style, no_if_expression, disable},
+ {elvis_style, no_import, disable},
+ {elvis_style, no_nested_try_catch, disable},
+ {elvis_style, no_operation_on_same_value, disable},
+ {elvis_style, no_receive_without_timeout, disable},
+ {elvis_style, no_single_clause_case, disable},
+ {elvis_style, no_spec_with_records, disable},
+ {elvis_style, no_throw, disable},
+ {elvis_style, operator_spaces, disable},
+ {elvis_style, param_pattern_matching, disable},
+ {elvis_style, private_data_types, disable},
+ {elvis_style, variable_naming_convention, disable}
+ ]
+ },
+
+ %#{dirs => ["include"],
+ % filter => "*.hrl",
+ % ruleset => hrl_files},
+
+ #{dirs => ["."],
+ filter => "Makefile.in",
+ ruleset => makefiles,
+ rules => [{elvis_text_style, line_length, #{limit => 400,
+ skip_comments => false}},
+ {elvis_style, dont_repeat_yourself, #{min_complexity => 20}}
+ ]
+ }
+ ]
+ }
+ ]
+ }
+].
+
+%% vim: set filetype=erlang tabstop=8:
diff --git a/erlang_ls.config b/erlang_ls.config
new file mode 100644
index 000000000..83e3e52a5
--- /dev/null
+++ b/erlang_ls.config
@@ -0,0 +1,32 @@
+#otp_path: "/usr/lib/erlang"
+#plt_path: "_build/default/rebar3_24.3.3_plt"
+#code_reload:
+# node: ejabberd@localhost
+apps_dirs:
+ - "_build/default/lib/*"
+deps_dirs:
+ - "_build/default/lib/*"
+include_dirs:
+ - "_build/default/lib"
+ - "_build/default/lib/*/include"
+ - "include"
+macros:
+ - name: DEPRECATED_GET_STACKTRACE
+ - name: HAVE_ERL_ERROR
+ - name: HAVE_URI_STRING
+ - name: OTP_BELOW_27
+ - name: SIP
+ - name: STUN
+diagnostics:
+ enabled:
+ - crossref
+ disabled:
+# - dialyzer
+ - unused_includes # Otherwise it complains about unused logger.hrl
+lenses:
+ disabled:
+ - ct-run-test
+ - function-references
+ - server-info
+ - show-behaviour-usages
+ - suggest-spec
diff --git a/examples/extauth/check_pass_null.pl b/examples/extauth/check_pass_null.pl
deleted file mode 100755
index cbf179202..000000000
--- a/examples/extauth/check_pass_null.pl
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/perl
-
-use Unix::Syslog qw(:macros :subs);
-
-my $domain = $ARGV[0] || "example.com";
-
-while(1)
- {
- # my $rin = '',$rout;
- # vec($rin,fileno(STDIN),1) = 1;
- # $ein = $rin;
- # my $nfound = select($rout=$rin,undef,undef,undef);
-
- my $buf = "";
- syslog LOG_INFO,"waiting for packet";
- my $nread = sysread STDIN,$buf,2;
- do { syslog LOG_INFO,"port closed"; exit; } unless $nread == 2;
- my $len = unpack "n",$buf;
- my $nread = sysread STDIN,$buf,$len;
-
- my ($op,$user,$host,$password) = split /:/,$buf;
- #$user =~ s/\./\//og;
- my $jid = "$user\@$domain";
- my $result;
-
- syslog(LOG_INFO,"request (%s)", $op);
-
- SWITCH:
- {
- $op eq 'auth' and do
- {
- $result = 1;
- },last SWITCH;
-
- $op eq 'setpass' and do
- {
- $result = 1;
- },last SWITCH;
-
- $op eq 'isuser' and do
- {
- # password is null. Return 1 if the user $user\@$domain exitst.
- $result = 1;
- },last SWITCH;
-
- $op eq 'tryregister' and do
- {
- $result = 1;
- },last SWITCH;
-
- $op eq 'removeuser' and do
- {
- # password is null. Return 1 if the user $user\@$domain exitst.
- $result = 1;
- },last SWITCH;
-
- $op eq 'removeuser3' and do
- {
- $result = 1;
- },last SWITCH;
- };
- my $out = pack "nn",2,$result ? 1 : 0;
- syswrite STDOUT,$out;
- }
-
-closelog;
diff --git a/examples/mtr/ejabberd b/examples/mtr/ejabberd
deleted file mode 100644
index 4328b0697..000000000
--- a/examples/mtr/ejabberd
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/sh
-#
-# PROVIDE: ejabberd
-# REQUIRE: DAEMON
-# KEYWORD: shutdown
-#
-
-HOME=/usr/pkg/jabber D=/usr/pkg/jabber/ejabberd export HOME
-
-name="ejabberd"
-rcvar=$name
-
-if [ -r /etc/rc.conf ]
-then
- . /etc/rc.conf
-else
- eval ${rcvar}=YES
-fi
-
-# $flags from environment overrides ${rcvar}_flags
-if [ -n "${flags}" ]
-then
- eval ${rcvar}_flags="${flags}"
-fi
-
-checkyesno()
-{
- eval _value=\$${1}
- case $_value in
- [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]|[Oo][Nn]|1) return 0 ;;
- [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]|[Oo][Ff][Ff]|0) return 1 ;;
- *)
- echo "\$${1} is not set properly."
- return 1
- ;;
- esac
-}
-
-cmd=${1:-start}
-case ${cmd} in
-force*)
- cmd=${cmd#force}
- eval ${rcvar}=YES
- ;;
-esac
-
-if checkyesno ${rcvar}
-then
-else
- exit 0
-fi
-
-case ${cmd} in
-start)
- if [ -x $D/src ]; then
- echo "Starting ${name}."
- cd $D/src
- ERL_MAX_PORTS=32000 export ERL_MAX_PORTS
- ulimit -n $ERL_MAX_PORTS
- su jabber -c "/usr/pkg/bin/erl -sname ejabberd -s ejabberd -heart -detached -sasl sasl_error_logger '{file, \"ejabberd-sasl.log\"}' &" \
- 1>/dev/null 2>&1
- fi
- ;;
-stop)
- echo "rpc:call('ejabberd@`hostname -s`', init, stop, [])." | \
- su jabber -c "/usr/pkg/bin/erl -sname ejabberdstop"
- ;;
-restart)
- echo "rpc:call('ejabberd@`hostname -s`', init, restart, [])." | \
- su jabber -c "/usr/pkg/bin/erl -sname ejabberdrestart"
- ;;
-*)
- echo "Usage: $0 {start|stop|restart}"
- exit 1
-esac
diff --git a/examples/mtr/ejabberd-netbsd.sh b/examples/mtr/ejabberd-netbsd.sh
deleted file mode 100644
index 31d01b6b8..000000000
--- a/examples/mtr/ejabberd-netbsd.sh
+++ /dev/null
@@ -1,81 +0,0 @@
-#!/bin/sh
-
-echo '1. fetch, compile, and install erlang'
-
-if [ ! pkg_info erlang 1>/dev/null 2>&1 ]; then
- cd /usr/pkgsrc/lang/erlang
- make fetch-list|sh
- make
- make install
-fi
-if pkg_info erlang | grep -q erlang-9.1nb1; then
-else
- echo "erlang-9.1nb1 not installed" 1>&2
- exit 1
-fi
-
-
-echo '2. install crypt_drv.so'
-
-if [ ! -d /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib ] ; then
- mkdir -p /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib
-fi
-if [ ! -f /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib/crypto_drv.so ]; then
- cp work/otp*/lib/crypto/priv/*/*/crypto_drv.so \
- /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib
-fi
-
-
-echo '3. compile and install elibcrypto.so'
-
-if [ ! -f /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib/elibcrypto.so ]; then
-cd /usr/pkgsrc/lang/erlang/work/otp_src_R9B-1/lib/crypto/c_src
-ld -r -u CRYPTO_set_mem_functions -u MD5 -u MD5_Init -u MD5_Update \
- -u MD5_Final -u SHA1 -u SHA1_Init -u SHA1_Update -u SHA1_Final \
- -u des_set_key -u des_ncbc_encrypt -u des_ede3_cbc_encrypt \
- -L/usr/lib -lcrypto -o ../priv/obj/i386--netbsdelf/elibcrypto.o
-cc -shared \
- -L/usr/pkgsrc/lang/erlang/work/otp_src_R9B-1/lib/erl_interface/obj/i386--netbsdelf \
- -o ../priv/obj/i386--netbsdelf/elibcrypto.so \
- ../priv/obj/i386--netbsdelf/elibcrypto.o -L/usr/lib -lcrypto
-cp ../priv/obj/i386--netbsdelf/elibcrypto.so \
- /usr/pkg/lib/erlang/lib/crypto-1.1.2.1/priv/lib
-fi
-
-
-echo '4. compile and install ssl_esock'
-
-if [ ! -f /usr/pkg/lib/erlang/lib/ssl-2.3.5/priv/bin/ssl_esock ]; then
- cd /usr/pkg/lib/erlang/lib/ssl-2.3.5/priv/obj/
- make
-fi
-
-
-echo '5. initial ejabberd configuration'
-
-cd /usr/pkg/jabber/ejabberd/src
-./configure
-
-
-echo '6. edit ejabberd Makefiles'
-
-for M in Makefile mod_*/Makefile; do
- if [ ! -f $M.orig ]; then
- mv $M $M.orig
- sed -e s%/usr/local%/usr/pkg%g < $M.orig > $M
- fi
-done
-
-
-echo '7. compile ejabberd'
-
-gmake
-for A in mod_muc mod_pubsub; do
- (cd $A; gmake)
-done
-
-
-echo ''
-echo 'now edit ejabberd.cfg'
-echo ''
-echo 'to start ejabberd: erl -sname ejabberd -s ejabberd'
diff --git a/examples/mtr/ejabberd.cfg b/examples/mtr/ejabberd.cfg
deleted file mode 100644
index b1023ee0e..000000000
--- a/examples/mtr/ejabberd.cfg
+++ /dev/null
@@ -1,65 +0,0 @@
-% jabber.dbc.mtview.ca.us
-
-override_acls.
-
-{acl, admin, {user, "mrose", "jabber.dbc.mtview.ca.us"}}.
-
-
-{access, announce, [{allow, admin},
- {deny, all}]}.
-{access, c2s, [{deny, blocked},
- {allow, all}]}.
-{access, c2s_shaper, [{none, admin},
- {normal, all}]}.
-{access, configure, [{allow, admin},
- {deny, all}]}.
-{access, disco_admin, [{allow, admin},
- {deny, all}]}.
-{access, muc_admin, [{allow, admin},
- {deny, all}]}.
-{access, register, [{deny, all}]}.
-{access, s2s_shaper, [{fast, all}]}.
-
-
-{auth_method, internal}.
-{host, "jabber.dbc.mtview.ca.us"}.
-{outgoing_s2s_port, 5269}.
-{shaper, normal, {maxrate, 1000}}.
-{shaper, fast, {maxrate, 50000}}.
-{welcome_message, none}.
-
-
-{listen, [{5222, ejabberd_c2s,
- [{access, c2s},
- {shaper, c2s_shaper}]},
- {5223, ejabberd_c2s,
- [{access, c2s},
- {shaper, c2s_shaper},
- {ssl, [{certfile, "/etc/openssl/certs/ejabberd.pem"}]}]},
- {5269, ejabberd_s2s_in,
- [{shaper, s2s_shaper}]}]}.
-
-
-{modules, [
- {mod_register, []},
- {mod_roster, []},
- {mod_privacy, []},
- {mod_configure, []},
- {mod_disco, []},
- {mod_stats, []},
- {mod_vcard, []},
- {mod_offline, []},
- {mod_echo, [{host, "echo.jabber.dbc.mtview.ca.us"}]},
- {mod_private, []},
- {mod_muc, []},
- {mod_pubsub, []},
- {mod_time, []},
- {mod_last, []},
- {mod_version, []}
- ]}.
-
-
-
-% Local Variables:
-% mode: erlang
-% End:
diff --git a/include/adhoc.hrl b/include/adhoc.hrl
deleted file mode 100644
index 2047db874..000000000
--- a/include/adhoc.hrl
+++ /dev/null
@@ -1,44 +0,0 @@
-%%%----------------------------------------------------------------------
-%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%----------------------------------------------------------------------
-
--record(adhoc_request,
-{
- lang = <<"">> :: binary(),
- node = <<"">> :: binary(),
- sessionid = <<"">> :: binary(),
- action = <<"">> :: binary(),
- xdata = false :: false | xmlel(),
- others = [] :: [xmlel()]
-}).
-
--record(adhoc_response,
-{
- lang = <<"">> :: binary(),
- node = <<"">> :: binary(),
- sessionid = <<"">> :: binary(),
- status :: atom(),
- defaultaction = <<"">> :: binary(),
- actions = [] :: [binary()],
- notes = [] :: [{binary(), binary()}],
- elements = [] :: [xmlel()]
-}).
-
--type adhoc_request() :: #adhoc_request{}.
--type adhoc_response() :: #adhoc_response{}.
diff --git a/include/bosh.hrl b/include/bosh.hrl
index ca43a569b..dd9f1b6a1 100644
--- a/include/bosh.hrl
+++ b/include/bosh.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_auth.hrl b/include/ejabberd_auth.hrl
index 00f31cfd3..bf7660d3f 100644
--- a/include/ejabberd_auth.hrl
+++ b/include/ejabberd_auth.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -18,5 +18,5 @@
%%%
%%%----------------------------------------------------------------------
--record(passwd, {us = {<<"">>, <<"">>} :: {binary(), binary()} | '$1',
+-record(passwd, {us = {<<"">>, <<"">>} :: {binary(), binary()} | {binary(), binary(), atom()} | '$1',
password = <<"">> :: binary() | scram() | '_'}).
diff --git a/include/ejabberd_commands.hrl b/include/ejabberd_commands.hrl
index d0f5ba70a..14d19d2e1 100644
--- a/include/ejabberd_commands.hrl
+++ b/include/ejabberd_commands.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -19,13 +19,30 @@
%%%----------------------------------------------------------------------
-type aterm() :: {atom(), atype()}.
--type atype() :: integer | string | binary |
+-type atype() :: integer | string | binary | any | atom |
{tuple, [aterm()]} | {list, aterm()}.
-type rterm() :: {atom(), rtype()}.
--type rtype() :: integer | string | atom |
+-type rtype() :: integer | string | atom | any |
{tuple, [rterm()]} | {list, rterm()} |
rescode | restuple.
+%% The 'any' and 'atom' argument types and 'any' result type
+%% should only be used %% by commands with tag 'internal',
+%% which are meant to be used only internally in ejabberd,
+%% and not called using external frontends.
+
+%% The purpose of a command can either be:
+%% - informative: its purpose is to obtain information
+%% - modifier: its purpose is to produce some change in the server
+%%
+%% A modifier command should be designed just to produce its desired side-effect,
+%% and its result term should just be success or failure: rescode or restuple.
+%%
+%% ejabberd_web_admin:make_command/2 considers that commands
+%% with result type different than rescode or restuple
+%% are commands that can be safely executed automatically
+%% to get information and build the web page.
+
-type oauth_scope() :: atom().
%% ejabberd_commands OAuth ReST ACL definition:
@@ -67,42 +84,24 @@
args_example = none :: none | [any()] | '_',
result_example = none :: any()}).
-%% TODO Fix me: Type is not up to date
--type ejabberd_commands() :: #ejabberd_commands{name :: atom(),
- tags :: [atom()],
- desc :: string(),
- longdesc :: string(),
- version :: integer(),
- module :: atom(),
- function :: atom(),
- args :: [aterm()],
- policy :: open | restricted | admin | user,
- access :: [{atom(),atom(),atom()}|atom()],
- result :: rterm()}.
+-type ejabberd_commands() :: #ejabberd_commands{name :: atom(),
+ tags :: [atom()],
+ desc :: string(),
+ longdesc :: string(),
+ version :: integer(),
+ note :: string(),
+ weight :: integer(),
+ module :: atom(),
+ function :: atom(),
+ args :: [aterm()],
+ policy :: open | restricted | admin | user,
+ access :: [{atom(),atom(),atom()}|atom()],
+ definer :: atom(),
+ result :: rterm(),
+ args_rename :: [{atom(),atom()}],
+ args_desc :: none | [string()] | '_',
+ result_desc :: none | string() | '_',
+ args_example :: none | [any()] | '_',
+ result_example :: any()
+ }.
-%% @type ejabberd_commands() = #ejabberd_commands{
-%% name = atom(),
-%% tags = [atom()],
-%% desc = string(),
-%% longdesc = string(),
-%% module = atom(),
-%% function = atom(),
-%% args = [aterm()],
-%% result = rterm()
-%% }.
-%% desc: Description of the command
-%% args: Describe the accepted arguments.
-%% This way the function that calls the command can format the
-%% arguments before calling.
-
-%% @type atype() = integer | string | {tuple, [aterm()]} | {list, aterm()}.
-%% Allowed types for arguments are integer, string, tuple and list.
-
-%% @type rtype() = integer | string | atom | {tuple, [rterm()]} | {list, rterm()} | rescode | restuple.
-%% A rtype is either an atom or a tuple with two elements.
-
-%% @type aterm() = {Name::atom(), Type::atype()}.
-%% An argument term is a tuple with the term name and the term type.
-
-%% @type rterm() = {Name::atom(), Type::rtype()}.
-%% A result term is a tuple with the term name and the term type.
diff --git a/include/ejabberd_ctl.hrl b/include/ejabberd_ctl.hrl
index e962e85be..cad82da89 100644
--- a/include/ejabberd_ctl.hrl
+++ b/include/ejabberd_ctl.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_http.hrl b/include/ejabberd_http.hrl
index 62e19a8f0..9e1373ce6 100644
--- a/include/ejabberd_http.hrl
+++ b/include/ejabberd_http.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_oauth.hrl b/include/ejabberd_oauth.hrl
index d9a5a09de..4798d9070 100644
--- a/include/ejabberd_oauth.hrl
+++ b/include/ejabberd_oauth.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_sm.hrl b/include/ejabberd_sm.hrl
index 92e85ae03..54a828e1a 100644
--- a/include/ejabberd_sm.hrl
+++ b/include/ejabberd_sm.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_sql.hrl b/include/ejabberd_sql.hrl
index 2d9ac03ec..d0ab55cba 100644
--- a/include/ejabberd_sql.hrl
+++ b/include/ejabberd_sql.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -34,12 +34,14 @@
format_query :: fun(),
format_res :: fun(),
args :: fun(),
+ flags :: non_neg_integer(),
loc :: {module(), pos_integer()}}).
-else.
-record(sql_query, {hash :: binary(),
format_query :: fun(),
format_res :: fun(),
args :: fun(),
+ flags :: non_neg_integer(),
loc :: {module(), {pos_integer(), pos_integer()}}}).
-endif.
@@ -48,3 +50,26 @@
boolean :: fun((boolean()) -> binary()),
in_array_string :: fun((binary()) -> binary()),
like_escape :: fun(() -> binary())}).
+
+
+-record(sql_index, {columns,
+ unique = false :: boolean(),
+ meta = #{}}).
+-record(sql_column, {name :: binary(),
+ type,
+ default = false,
+ opts = []}).
+-record(sql_table, {name :: binary(),
+ columns :: [#sql_column{}],
+ indices = [] :: [#sql_index{}],
+ post_create}).
+-record(sql_schema, {version :: integer(),
+ tables :: [#sql_table{}],
+ update = []}).
+-record(sql_references, {table :: binary(),
+ column :: binary()}).
+
+-record(sql_schema_info,
+ {db_type :: pgsql | mysql | sqlite,
+ db_version :: any(),
+ new_schema = true :: boolean()}).
diff --git a/include/ejabberd_sql_pt.hrl b/include/ejabberd_sql_pt.hrl
index 07479d440..f89f5c969 100644
--- a/include/ejabberd_sql_pt.hrl
+++ b/include/ejabberd_sql_pt.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_stacktrace.hrl b/include/ejabberd_stacktrace.hrl
deleted file mode 100644
index cc07c6eab..000000000
--- a/include/ejabberd_stacktrace.hrl
+++ /dev/null
@@ -1,27 +0,0 @@
-%%%----------------------------------------------------------------------
-%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
-%%%
-%%% This program is free software; you can redistribute it and/or
-%%% modify it under the terms of the GNU General Public License as
-%%% published by the Free Software Foundation; either version 2 of the
-%%% License, or (at your option) any later version.
-%%%
-%%% This program is distributed in the hope that it will be useful,
-%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
-%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-%%% General Public License for more details.
-%%%
-%%% You should have received a copy of the GNU General Public License along
-%%% with this program; if not, write to the Free Software Foundation, Inc.,
-%%% 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-%%%
-%%%----------------------------------------------------------------------
-
--ifdef(DEPRECATED_GET_STACKTRACE).
--define(EX_RULE(Class, Reason, Stack), Class:Reason:Stack).
--define(EX_STACK(Stack), Stack).
--else.
--define(EX_RULE(Class, Reason, _), Class:Reason).
--define(EX_STACK(_), erlang:get_stacktrace()).
--endif.
diff --git a/include/ejabberd_web_admin.hrl b/include/ejabberd_web_admin.hrl
index 25df7f0c0..45e4beada 100644
--- a/include/ejabberd_web_admin.hrl
+++ b/include/ejabberd_web_admin.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -62,6 +62,11 @@
[{<<"type">>, Type}, {<<"name">>, Name},
{<<"value">>, Value}])).
+-define(INPUTPH(Type, Name, Value, PlaceHolder),
+ ?XA(<<"input">>,
+ [{<<"type">>, Type}, {<<"name">>, Name},
+ {<<"value">>, Value}, {<<"placeholder">>, PlaceHolder}])).
+
-define(INPUTT(Type, Name, Value),
?INPUT(Type, Name, (translate:translate(Lang, Value)))).
@@ -95,16 +100,27 @@
-define(XRES(Text),
?XAC(<<"p">>, [{<<"class">>, <<"result">>}], Text)).
+-define(DIVRES(Elements),
+ ?XAE(<<"div">>, [{<<"class">>, <<"result">>}], Elements)).
+
%% Guide Link
-define(XREST(Text), ?XRES((translate:translate(Lang, Text)))).
-define(GL(Ref, Title),
?XAE(<<"div">>, [{<<"class">>, <<"guidelink">>}],
[?XAE(<<"a">>,
- [{<<"href">>, <<"https://docs.ejabberd.im/admin/configuration/", Ref/binary>>},
+ [{<<"href">>, <<"https://docs.ejabberd.im/", Ref/binary>>},
{<<"target">>, <<"_blank">>}],
[?C(<<"docs: ", Title/binary>>)])])).
%% h1 with a Guide Link
--define(H1GL(Name, Ref, Title),
- [?XC(<<"h1">>, Name), ?GL(Ref, Title)]).
+-define(H1GLraw(Name, Ref, Title),
+ [?XC(<<"h1">>, Name), ?GL(Ref, Title), ?BR, ?BR]).
+-define(H1GL(Name, RefConf, Title),
+ ?H1GLraw(Name, <<"admin/configuration/", RefConf/binary>>, Title)).
+
+-define(ANCHORL(Ref),
+ ?XAE(<<"div">>, [{<<"class">>, <<"anchorlink">>}],
+ [?XAE(<<"a">>,
+ [{<<"href">>, <<"#", Ref/binary>>}],
+ [?C(unicode:characters_to_binary("¶"))])])).
diff --git a/include/eldap.hrl b/include/eldap.hrl
index db4f5428a..0b6dc97e5 100644
--- a/include/eldap.hrl
+++ b/include/eldap.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/http_bind.hrl b/include/http_bind.hrl
index a94379ee0..ab1294e7d 100644
--- a/include/http_bind.hrl
+++ b/include/http_bind.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/logger.hrl b/include/logger.hrl
index d69ff0d07..e41ab73dd 100644
--- a/include/logger.hrl
+++ b/include/logger.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -39,20 +39,46 @@
-else.
-include_lib("kernel/include/logger.hrl").
+-define(CLEAD, "\e[1"). % bold
+-define(CMID, "\e[0"). % normal
+-define(CCLEAN, "\e[0m"). % clean
+
+-define(CDEFAULT, ";49;95m"). % light magenta
+-define(CDEBUG, ";49;90m"). % dark gray
+-define(CINFO, ";49;92m"). % green
+-define(CWARNING, ";49;93m"). % light yellow
+-define(CERROR, ";49;91m"). % light magenta
+-define(CCRITICAL,";49;31m"). % light red
+
-define(DEBUG(Format, Args),
- begin ?LOG_DEBUG(Format, Args), ok end).
+ begin ?LOG_DEBUG(Format, Args,
+ #{clevel => ?CLEAD ++ ?CDEBUG,
+ ctext => ?CMID ++ ?CDEBUG}),
+ ok end).
-define(INFO_MSG(Format, Args),
- begin ?LOG_INFO(Format, Args), ok end).
+ begin ?LOG_INFO(Format, Args,
+ #{clevel => ?CLEAD ++ ?CINFO,
+ ctext => ?CCLEAN}),
+ ok end).
-define(WARNING_MSG(Format, Args),
- begin ?LOG_WARNING(Format, Args), ok end).
+ begin ?LOG_WARNING(Format, Args,
+ #{clevel => ?CLEAD ++ ?CWARNING,
+ ctext => ?CMID ++ ?CWARNING}),
+ ok end).
-define(ERROR_MSG(Format, Args),
- begin ?LOG_ERROR(Format, Args), ok end).
+ begin ?LOG_ERROR(Format, Args,
+ #{clevel => ?CLEAD ++ ?CERROR,
+ ctext => ?CMID ++ ?CERROR}),
+ ok end).
-define(CRITICAL_MSG(Format, Args),
- begin ?LOG_CRITICAL(Format, Args), ok end).
+ begin ?LOG_CRITICAL(Format, Args,
+ #{clevel => ?CLEAD++ ?CCRITICAL,
+ ctext => ?CMID ++ ?CCRITICAL}),
+ ok end).
-endif.
%% Use only when trying to troubleshoot test problem with ExUnit
diff --git a/include/mod_announce.hrl b/include/mod_announce.hrl
index 9c7647272..77badf90e 100644
--- a/include/mod_announce.hrl
+++ b/include/mod_announce.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/ejabberd_config.hrl b/include/mod_antispam.hrl
similarity index 59%
rename from include/ejabberd_config.hrl
rename to include/mod_antispam.hrl
index 555d998b7..c30f24620 100644
--- a/include/ejabberd_config.hrl
+++ b/include/mod_antispam.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -18,13 +18,19 @@
%%%
%%%----------------------------------------------------------------------
--record(local_config, {key :: any(), value :: any()}).
+-define(MODULE_ANTISPAM, mod_antispam).
--type local_config() :: #local_config{}.
+-type url() :: binary().
+-type filename() :: binary() | none | false.
+-type jid_set() :: sets:set(ljid()).
+-type url_set() :: sets:set(url()).
--record(state,
- {opts = [] :: [acl:acl() | local_config()],
- hosts = [] :: [binary()],
- override_local = false :: boolean(),
- override_global = false :: boolean(),
- override_acls = false :: boolean()}).
+-define(DEFAULT_RTBL_DOMAINS_NODE, <<"spam_source_domains">>).
+
+-record(rtbl_service,
+ {host = none :: binary() | none,
+ node = ?DEFAULT_RTBL_DOMAINS_NODE :: binary(),
+ subscribed = false :: boolean(),
+ retry_timer = undefined :: reference() | undefined}).
+
+-type rtbl_service() :: #rtbl_service{}.
diff --git a/include/mod_caps.hrl b/include/mod_caps.hrl
index aa5287069..ee1bbe44e 100644
--- a/include/mod_caps.hrl
+++ b/include/mod_caps.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_last.hrl b/include/mod_last.hrl
index 6b2ae7d78..b1c13621a 100644
--- a/include/mod_last.hrl
+++ b/include/mod_last.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_mam.hrl b/include/mod_mam.hrl
index 494c4bd5a..77ea54a5e 100644
--- a/include/mod_mam.hrl
+++ b/include/mod_mam.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -26,7 +26,8 @@
bare_peer = {<<"">>, <<"">>, <<"">>} :: ljid(),
packet = #xmlel{} :: xmlel() | message(),
nick = <<"">> :: binary(),
- type = chat :: chat | groupchat}).
+ type = chat :: chat | groupchat,
+ origin_id = <<"">> :: binary()}).
-record(archive_prefs,
{us = {<<"">>, <<"">>} :: {binary(), binary()},
diff --git a/include/mod_vcard_xupdate.hrl b/include/mod_matrix_gw.hrl
similarity index 55%
rename from include/mod_vcard_xupdate.hrl
rename to include/mod_matrix_gw.hrl
index 9b5bfac30..cdb272e8e 100644
--- a/include/mod_vcard_xupdate.hrl
+++ b/include/mod_matrix_gw.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -18,5 +18,19 @@
%%%
%%%----------------------------------------------------------------------
--record(vcard_xupdate, {us = {<<>>, <<>>} :: {binary(), binary()},
- hash = <<>> :: binary()}).
+-record(room_version,
+ {id :: binary(),
+ %% use the same field names as in Synapse
+ enforce_key_validity :: boolean(),
+ special_case_aliases_auth :: boolean(),
+ strict_canonicaljson :: boolean(),
+ limit_notifications_power_levels :: boolean(),
+ knock_join_rule :: boolean(),
+ restricted_join_rule :: boolean(),
+ restricted_join_rule_fix :: boolean(),
+ knock_restricted_join_rule :: boolean(),
+ enforce_int_power_levels :: boolean(),
+ implicit_room_creator :: boolean(),
+ updated_redaction_rules :: boolean(),
+ hydra :: boolean()
+ }).
diff --git a/include/mod_muc.hrl b/include/mod_muc.hrl
index e31e01be0..f801b29e1 100644
--- a/include/mod_muc.hrl
+++ b/include/mod_muc.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_muc_room.hrl b/include/mod_muc_room.hrl
index cc00f73c8..5f81fe026 100644
--- a/include/mod_muc_room.hrl
+++ b/include/mod_muc_room.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -38,13 +38,13 @@
description = <<"">> :: binary(),
allow_change_subj = true :: boolean(),
allow_query_users = true :: boolean(),
- allow_private_messages = true :: boolean(),
+ allowpm = anyone :: anyone | participants | moderators | none,
allow_private_messages_from_visitors = anyone :: anyone | moderators | nobody ,
allow_visitor_status = true :: boolean(),
allow_visitor_nickchange = true :: boolean(),
public = true :: boolean(),
public_list = true :: boolean(),
- persistent = false :: boolean(),
+ persistent = false :: boolean() | {destroying, boolean()},
moderated = true :: boolean(),
captcha_protected = false :: boolean(),
members_by_default = true :: boolean(),
@@ -122,10 +122,12 @@
robots = #{} :: robots(),
nicks = #{} :: nicks(),
affiliations = #{} :: affiliations(),
+ roles = #{} :: roles(),
history = #lqueue{} :: lqueue(),
subject = [] :: [text()],
- subject_author = <<"">> :: binary(),
- hats_users = #{} :: map(), % FIXME on OTP 21+: #{ljid() => #{binary() => binary()}},
+ subject_author = {<<"">>, #jid{}} :: {binary(), jid()},
+ hats_defs = #{} :: #{binary() => {binary(), binary()}},
+ hats_users = #{} :: #{ljid() => [binary()]},
just_created = erlang:system_time(microsecond) :: true | integer(),
activity = treap:empty() :: treap:treap(),
room_shaper = none :: ejabberd_shaper:shaper(),
@@ -137,3 +139,4 @@
-type robots() :: #{jid() => {binary(), stanza()}}.
-type nicks() :: #{binary() => [ljid()]}.
-type affiliations() :: #{ljid() => affiliation() | {affiliation(), binary()}}.
+-type roles() :: #{ljid() => role() | {role(), binary()}}.
diff --git a/include/mod_offline.hrl b/include/mod_offline.hrl
index 8b78f2e16..e1bb236f6 100644
--- a/include/mod_offline.hrl
+++ b/include/mod_offline.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_privacy.hrl b/include/mod_privacy.hrl
index 1f481eec8..8118a6de6 100644
--- a/include/mod_privacy.hrl
+++ b/include/mod_privacy.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_private.hrl b/include/mod_private.hrl
index 1c551a212..05adc7d8b 100644
--- a/include/mod_private.hrl
+++ b/include/mod_private.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_proxy65.hrl b/include/mod_proxy65.hrl
index be2797bca..4f017124a 100644
--- a/include/mod_proxy65.hrl
+++ b/include/mod_proxy65.hrl
@@ -2,7 +2,7 @@
%%% RFC 1928 constants.
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_push.hrl b/include/mod_push.hrl
index 9ad1e0405..8a9de102b 100644
--- a/include/mod_push.hrl
+++ b/include/mod_push.hrl
@@ -1,5 +1,5 @@
%%%----------------------------------------------------------------------
-%%% ejabberd, Copyright (C) 2017-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2017-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_roster.hrl b/include/mod_roster.hrl
index 27d2aab28..a056dd22c 100644
--- a/include/mod_roster.hrl
+++ b/include/mod_roster.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_shared_roster.hrl b/include/mod_shared_roster.hrl
index 515243862..4c35878e8 100644
--- a/include/mod_shared_roster.hrl
+++ b/include/mod_shared_roster.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mod_vcard.hrl b/include/mod_vcard.hrl
index 24b219ec5..d97e5c900 100644
--- a/include/mod_vcard.hrl
+++ b/include/mod_vcard.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/include/mqtt.hrl b/include/mqtt.hrl
index 4d3ff5672..bf910368f 100644
--- a/include/mqtt.hrl
+++ b/include/mqtt.hrl
@@ -1,6 +1,6 @@
%%%-------------------------------------------------------------------
%%% @author Evgeny Khramtsov
-%%% @copyright (C) 2002-2021 ProcessOne, SARL. All Rights Reserved.
+%%% @copyright (C) 2002-2025 ProcessOne, SARL. All Rights Reserved.
%%%
%%% Licensed under the Apache License, Version 2.0 (the "License");
%%% you may not use this file except in compliance with the License.
diff --git a/include/pubsub.hrl b/include/pubsub.hrl
index da919e9e2..316be342a 100644
--- a/include/pubsub.hrl
+++ b/include/pubsub.hrl
@@ -1,6 +1,6 @@
%%%----------------------------------------------------------------------
%%%
-%%% ejabberd, Copyright (C) 2002-2021 ProcessOne
+%%% ejabberd, Copyright (C) 2002-2025 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
diff --git a/install-sh b/install-sh
old mode 100644
new mode 100755
diff --git a/lib/ejabberd/config/attr.ex b/lib/ejabberd/config/attr.ex
index 9d17b157d..85d19191b 100644
--- a/lib/ejabberd/config/attr.ex
+++ b/lib/ejabberd/config/attr.ex
@@ -41,7 +41,7 @@ defmodule Ejabberd.Config.Attr do
"""
@spec validate([attr]) :: [{:ok, attr}] | [{:error, attr, atom()}]
def validate(attrs) when is_list(attrs), do: Enum.map(attrs, &valid_attr?/1)
- def validate(attr), do: validate([attr]) |> List.first
+ def validate(attr), do: validate([attr])
@doc """
Returns the type of an attribute, given its name.
diff --git a/lib/ejabberd/config/config.ex b/lib/ejabberd/config/config.ex
index a1b91858a..a8805e612 100644
--- a/lib/ejabberd/config/config.ex
+++ b/lib/ejabberd/config/config.ex
@@ -36,8 +36,8 @@ defmodule Ejabberd.Config do
case force do
true ->
- Ejabberd.Config.Store.stop
- Ejabberd.Config.Store.start_link
+ Ejabberd.Config.Store.stop()
+ Ejabberd.Config.Store.start_link()
do_init(file_path)
false ->
if not init_already_executed, do: do_init(file_path)
@@ -105,11 +105,8 @@ defmodule Ejabberd.Config do
Code.eval_file(file_path) |> extract_and_store_module_name()
# Getting start/0 config
- Ejabberd.Config.Store.get(:module_name)
- |> case do
- nil -> IO.puts "[ ERR ] Configuration module not found."
- [module] -> call_start_func_and_store_data(module)
- end
+ [module] = Ejabberd.Config.Store.get(:module_name)
+ call_start_func_and_store_data(module)
# Fetching git modules and install them
get_modules_parsed_in_order()
diff --git a/lib/ejabberd/config/ejabberd_hook.ex b/lib/ejabberd/config/ejabberd_hook.ex
index 8b7858d23..5f9de4aa0 100644
--- a/lib/ejabberd/config/ejabberd_hook.ex
+++ b/lib/ejabberd/config/ejabberd_hook.ex
@@ -13,7 +13,6 @@ defmodule Ejabberd.Config.EjabberdHook do
@doc """
Register a hook to ejabberd.
"""
- @spec start(EjabberdHook.t) :: none
def start(%EjabberdHook{hook: hook, opts: opts, fun: fun}) do
host = Keyword.get(opts, :host, :global)
priority = Keyword.get(opts, :priority, 50)
diff --git a/lib/ejabberd/config/ejabberd_module.ex b/lib/ejabberd/config/ejabberd_module.ex
index 6a74fe460..6d5b1e467 100644
--- a/lib/ejabberd/config/ejabberd_module.ex
+++ b/lib/ejabberd/config/ejabberd_module.ex
@@ -7,12 +7,13 @@ defmodule Ejabberd.Config.EjabberdModule do
the already existing Elixir.Module.
"""
- @type t :: %{module: atom, attrs: [Attr.t]}
-
- defstruct [:module, :attrs]
-
alias Ejabberd.Config.EjabberdModule
alias Ejabberd.Config.Validation
+ alias Ejabberd.Config.Attr
+
+ @type t :: %{module: atom, attrs: [Attr.attr]}
+
+ defstruct [:module, :attrs]
@doc """
Given a list of modules / single module
@@ -29,7 +30,6 @@ defmodule Ejabberd.Config.EjabberdModule do
a git attribute and tries to fetch the repo,
then, it install them through :ext_mod.install/1
"""
- @spec fetch_git_repos([EjabberdModule.t]) :: none()
def fetch_git_repos(modules) do
modules
|> Enum.filter(&is_git_module?/1)
@@ -60,7 +60,7 @@ defmodule Ejabberd.Config.EjabberdModule do
defp fetch_and_store_repo_source_if_not_exists(path, repo) do
unless File.exists?(path) do
IO.puts "[info] Fetching: #{repo}"
- :os.cmd('git clone #{repo} #{path}')
+ :os.cmd(~c"git clone #{repo} #{path}")
end
end
diff --git a/lib/ejabberd/config/logger/ejabberd_logger.ex b/lib/ejabberd/config/logger/ejabberd_logger.ex
index 90970ba73..822571916 100644
--- a/lib/ejabberd/config/logger/ejabberd_logger.ex
+++ b/lib/ejabberd/config/logger/ejabberd_logger.ex
@@ -17,9 +17,9 @@ defmodule Ejabberd.Config.EjabberdLogger do
end
defp do_log_errors({:ok, _mod}), do: nil
- defp do_log_errors({:error, _mod, errors}), do: Enum.each errors, &do_log_errors/1
- defp do_log_errors({:attribute, errors}), do: Enum.each errors, &log_attribute_error/1
- defp do_log_errors({:dependency, errors}), do: Enum.each errors, &log_dependency_error/1
+ defp do_log_errors({:error, _mod, errors}), do: (Enum.each errors, &do_log_errors/1)
+ defp do_log_errors({:attribute, errors}), do: (Enum.each errors, &log_attribute_error/1)
+ defp do_log_errors({:dependency, errors}), do: (Enum.each errors, &log_dependency_error/1)
defp log_attribute_error({{attr_name, _val}, :attr_not_supported}), do:
IO.puts "[ WARN ] Annotation @#{attr_name} is not supported."
diff --git a/lib/ejabberd/config/opts_formatter.ex b/lib/ejabberd/config/opts_formatter.ex
index b7010ddfe..3d3db926f 100644
--- a/lib/ejabberd/config/opts_formatter.ex
+++ b/lib/ejabberd/config/opts_formatter.ex
@@ -14,15 +14,12 @@ defmodule Ejabberd.Config.OptsFormatter do
Look at how Config.get_ejabberd_opts/0 is constructed for
more informations.
"""
- @spec format_opts_for_ejabberd([{atom(), any()}]) :: list()
+ @spec format_opts_for_ejabberd(map) :: list()
def format_opts_for_ejabberd(opts) do
opts
|> format_attrs_for_ejabberd
end
- defp format_attrs_for_ejabberd(opts) when is_list(opts),
- do: Enum.map opts, &format_attrs_for_ejabberd/1
-
defp format_attrs_for_ejabberd({:listeners, mods}),
do: {:listen, format_listeners_for_ejabberd(mods)}
@@ -32,6 +29,9 @@ defmodule Ejabberd.Config.OptsFormatter do
defp format_attrs_for_ejabberd({key, opts}) when is_atom(key),
do: {key, opts}
+ defp format_attrs_for_ejabberd(opts),
+ do: (Enum.map opts, &format_attrs_for_ejabberd/1)
+
defp format_mods_for_ejabberd(mods) do
Enum.map mods, fn %EjabberdModule{module: mod, attrs: attrs} ->
{mod, attrs[:opts]}
diff --git a/lib/ejabberd/config/validator/validation.ex b/lib/ejabberd/config/validator/validation.ex
index af582676e..227a3545f 100644
--- a/lib/ejabberd/config/validator/validation.ex
+++ b/lib/ejabberd/config/validator/validation.ex
@@ -3,12 +3,12 @@ defmodule Ejabberd.Config.Validation do
Module used to validate a list of modules.
"""
- @type mod_validation :: {[EjabberdModule.t], EjabberdModule.t, map}
- @type mod_validation_result :: {:ok, EjabberdModule.t} | {:error, EjabberdModule.t, map}
-
alias Ejabberd.Config.EjabberdModule
alias Ejabberd.Config.Validator
+ @type mod_validation :: {[EjabberdModule.t], EjabberdModule.t, map}
+ @type mod_validation_result :: {:ok, EjabberdModule.t} | {:error, EjabberdModule.t, map}
+
@doc """
Given a module or a list of modules it runs validators on them
and returns {:ok, mod} or {:error, mod, errors}, for each
diff --git a/lib/ejabberd/config/validator/validator_attrs.ex b/lib/ejabberd/config/validator/validator_attrs.ex
index 6a85c068d..e0e133b61 100644
--- a/lib/ejabberd/config/validator/validator_attrs.ex
+++ b/lib/ejabberd/config/validator/validator_attrs.ex
@@ -3,11 +3,12 @@ defmodule Ejabberd.Config.Validator.Attrs do
Validator module used to validate attributes.
"""
- # TODO: Duplicated from validator.ex !!!
- @type mod_validation :: {[EjabberdModule.t], EjabberdModule.t, map}
-
import Ejabberd.Config.ValidatorUtility
alias Ejabberd.Config.Attr
+ alias Ejabberd.Config.EjabberdModule
+
+ # TODO: Duplicated from validator.ex !!!
+ @type mod_validation :: {[EjabberdModule.t], EjabberdModule.t, map}
@doc """
Given a module (with the form used for validation)
@@ -17,9 +18,9 @@ defmodule Ejabberd.Config.Validator.Attrs do
@spec validate(mod_validation) :: mod_validation
def validate({modules, mod, errors}) do
errors = Enum.reduce mod.attrs, errors, fn(attr, err) ->
- case Attr.validate(attr) do
- {:ok, _attr} -> err
- {:error, attr, cause} -> put_error(err, :attribute, {attr, cause})
+ case Attr.validate([attr]) do
+ [{:ok, _attr}] -> err
+ [{:error, attr, cause}] -> put_error(err, :attribute, {attr, cause})
end
end
diff --git a/lib/ejabberd/config/validator/validator_dependencies.ex b/lib/ejabberd/config/validator/validator_dependencies.ex
index d44c8a136..4eb466663 100644
--- a/lib/ejabberd/config/validator/validator_dependencies.ex
+++ b/lib/ejabberd/config/validator/validator_dependencies.ex
@@ -4,6 +4,8 @@ defmodule Ejabberd.Config.Validator.Dependencies do
with the @dependency annotation.
"""
+ alias Ejabberd.Config.EjabberdModule
+
# TODO: Duplicated from validator.ex !!!
@type mod_validation :: {[EjabberdModule.t], EjabberdModule.t, map}
import Ejabberd.Config.ValidatorUtility
diff --git a/lib/ejabberd/config/validator/validator_utility.ex b/lib/ejabberd/config/validator/validator_utility.ex
index 17805f748..6047618b6 100644
--- a/lib/ejabberd/config/validator/validator_utility.ex
+++ b/lib/ejabberd/config/validator/validator_utility.ex
@@ -4,8 +4,6 @@ defmodule Ejabberd.Config.ValidatorUtility do
Imports utility functions for working with validation structures.
"""
- alias Ejabberd.Config.EjabberdModule
-
@doc """
Inserts an error inside the errors collection, for the given key.
If the key doesn't exists then it creates an empty collection
@@ -22,7 +20,6 @@ defmodule Ejabberd.Config.ValidatorUtility do
Given a list of modules it extracts and returns a list
of the module names (which are Elixir.Module).
"""
- @spec extract_module_names(EjabberdModule.t) :: [atom]
def extract_module_names(modules) when is_list(modules) do
modules
|> Enum.map(&Map.get(&1, :module))
diff --git a/lib/ejabberd/config_util.ex b/lib/ejabberd/config_util.ex
index 6592104a2..71d854f15 100644
--- a/lib/ejabberd/config_util.ex
+++ b/lib/ejabberd/config_util.ex
@@ -7,7 +7,7 @@ defmodule Ejabberd.ConfigUtil do
@doc """
Returns true when the config file is based on elixir.
"""
- @spec is_elixir_config(list) :: boolean
+ @spec is_elixir_config(binary) :: boolean
def is_elixir_config(filename) when is_list(filename) do
is_elixir_config(to_string(filename))
end
diff --git a/lib/ejabberd/module.ex b/lib/ejabberd/module.ex
deleted file mode 100644
index 9fb3f040c..000000000
--- a/lib/ejabberd/module.ex
+++ /dev/null
@@ -1,19 +0,0 @@
-defmodule Ejabberd.Module do
-
- defmacro __using__(opts) do
- logger_enabled = Keyword.get(opts, :logger, true)
-
- quote do
- @behaviour :gen_mod
- import Ejabberd.Module
-
- unquote(if logger_enabled do
- quote do: import Ejabberd.Logger
- end)
- end
- end
-
- # gen_mod callbacks
- def depends(_host, _opts), do: []
- def mod_opt_type(_), do: []
-end
diff --git a/lib/ejabberd_auth_example.ex b/lib/ejabberd_auth_example.ex
new file mode 100644
index 000000000..5bc37e093
--- /dev/null
+++ b/lib/ejabberd_auth_example.ex
@@ -0,0 +1,44 @@
+defmodule Ejabberd.Auth.Example do
+
+ @moduledoc """
+ Example ejabberd auth method written in Elixir.
+
+ This is an example to demonstrate the usage of Elixir to
+ create ejabberd auth methods.
+
+ Example configuration:
+ auth_method: 'Ejabberd.Auth.Example'
+ """
+
+ @behaviour :ejabberd_auth
+ import Ejabberd.Logger
+
+ @impl true
+ def start(host) do
+ info("Starting Ejabberd.Auth.Example to authenticate '#{host}' users")
+ nil
+ end
+
+ @impl true
+ def stop(host) do
+ info("Stopping Ejabberd.Auth.Example to authenticate '#{host}' users")
+ nil
+ end
+
+ @impl true
+ def check_password("alice", _authz_id, _host, "secret"), do: {:nocache, true}
+ def check_password(_username, _authz_id, _host, _secret), do: {:nocache, false}
+
+ @impl true
+ def user_exists("alice", _host), do: {:nocache, true}
+ def user_exists(_username, _host), do: {:nocache, false}
+
+ @impl true
+ def plain_password_required(_binary), do: true
+
+ @impl true
+ def store_type(_host), do: :external
+
+ @impl true
+ def use_cache(_host), do: false
+end
diff --git a/lib/mix/tasks/deps.tree.ex b/lib/mix/tasks/deps.tree.ex
index a3439c40b..e93b4aa48 100644
--- a/lib/mix/tasks/deps.tree.ex
+++ b/lib/mix/tasks/deps.tree.ex
@@ -14,15 +14,15 @@ defmodule Mix.Tasks.Ejabberd.Deps.Tree do
def run(_argv) do
# First we need to start manually the store to be available
# during the compilation of the config file.
- Ejabberd.Config.Store.start_link
+ Ejabberd.Config.Store.start_link()
Ejabberd.Config.init(:ejabberd_config.path())
- Mix.shell.info "ejabberd modules"
+ Mix.shell().info "ejabberd modules"
Ejabberd.Config.Store.get(:modules)
|> Enum.reverse # Because of how mods are stored inside the store
|> format_mods
- |> Mix.shell.info
+ |> Mix.shell().info
end
defp format_mods(mods) when is_list(mods) do
diff --git a/lib/mod_example.ex b/lib/mod_example.ex
new file mode 100644
index 000000000..12166810a
--- /dev/null
+++ b/lib/mod_example.ex
@@ -0,0 +1,46 @@
+defmodule Ejabberd.Module.Example do
+
+ @moduledoc """
+ Example ejabberd module written in Elixir.
+
+ This is an example to demonstrate the usage of Elixir to
+ create ejabberd modules.
+
+ Example configuration:
+ modules:
+ 'Ejabberd.Module.Example': {}
+ """
+
+ @behaviour :gen_mod
+ import Ejabberd.Logger
+
+ def start(host, _opts) do
+ info("Starting Ejabberd.Module.Example for host '#{host}'")
+ Ejabberd.Hooks.add(:set_presence_hook, host, __MODULE__, :on_presence, 50)
+ :ok
+ end
+
+ def stop(host) do
+ info("Stopping Ejabberd.Module.Example for host '#{host}'")
+ Ejabberd.Hooks.delete(:set_presence_hook, host, __MODULE__, :on_presence, 50)
+ :ok
+ end
+
+ def on_presence(user, _server, _resource, _packet) do
+ info("Receive presence for #{user}")
+ :none
+ end
+
+ def depends(_host, _opts) do
+ []
+ end
+
+ def mod_options(_host) do
+ []
+ end
+
+ def mod_doc() do
+ %{:desc => "This is just a demonstration."}
+ end
+
+end
diff --git a/lib/mod_presence_demo.ex b/lib/mod_presence_demo.ex
deleted file mode 100644
index f41a53a31..000000000
--- a/lib/mod_presence_demo.ex
+++ /dev/null
@@ -1,33 +0,0 @@
-defmodule ModPresenceDemo do
- use Ejabberd.Module
-
- def start(host, _opts) do
- info('Starting ejabberd module Presence Demo')
- Ejabberd.Hooks.add(:set_presence_hook, host, __MODULE__, :on_presence, 50)
- :ok
- end
-
- def stop(host) do
- info('Stopping ejabberd module Presence Demo')
- Ejabberd.Hooks.delete(:set_presence_hook, host, __MODULE__, :on_presence, 50)
- :ok
- end
-
- def on_presence(user, _server, _resource, _packet) do
- info('Receive presence for #{user}')
- :none
- end
-
- def depends(_host, _opts) do
- []
- end
-
- def mod_options(_host) do
- []
- end
-
- def mod_doc() do
- %{:desc => 'This is just a demonstration.'}
- end
-
-end
diff --git a/m4/erlang-extra.m4 b/m4/erlang-extra.m4
index 4a7311bad..95c4b138d 100644
--- a/m4/erlang-extra.m4
+++ b/m4/erlang-extra.m4
@@ -75,7 +75,7 @@ EOF
if test "x`cat conftest.out`" != "xok"; then
AC_MSG_RESULT([failed])
X="`cat conftest.out`"
- if test "[$3]" == "warn"; then
+ if test "[$3]" = "warn"; then
AC_MSG_WARN([$X])
else
AC_MSG_FAILURE([$X])
diff --git a/man/ejabberd.yml.5 b/man/ejabberd.yml.5
index 8fb59c381..aa42e20b2 100644
--- a/man/ejabberd.yml.5
+++ b/man/ejabberd.yml.5
@@ -1,13 +1,13 @@
'\" t
.\" Title: ejabberd.yml
.\" Author: [see the "AUTHOR" section]
-.\" Generator: DocBook XSL Stylesheets v1.79.1
-.\" Date: 12/08/2021
+.\" Generator: DocBook XSL Stylesheets vsnapshot
+.\" Date: 08/22/2025
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
-.TH "EJABBERD\&.YML" "5" "12/08/2021" "\ \&" "\ \&"
+.TH "EJABBERD\&.YML" "5" "08/22/2025" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -52,7 +52,7 @@ YAML is indentation sensitive, so make sure you respect indentation, or otherwis
.sp .5v
.RE
.sp
-Logically, configuration options are splitted into 3 main categories: \fIModules\fR, \fIListeners\fR and everything else called \fITop Level\fR options\&. Thus this document is splitted into 3 main chapters describing each category separately\&. So, the contents of ejabberd\&.yml will typically look like this:
+Logically, configuration options are split into 3 main categories: \fIModules\fR, \fIListeners\fR and everything else called \fITop Level\fR options\&. Thus this document is split into 3 main chapters describing each category separately\&. So, the contents of ejabberd\&.yml will typically look like this:
.sp
.if n \{\
.RS 4
@@ -82,16 +82,17 @@ All options can be changed in runtime by running \fIejabberdctl reload\-config\f
.sp
Some options can be specified for particular virtual host(s) only using \fIhost_config\fR or \fIappend_host_config\fR options\&. Such options are called \fIlocal\fR\&. Examples are \fImodules\fR, \fIauth_method\fR and \fIdefault_db\fR\&. The options that cannot be defined per virtual host are called \fIglobal\fR\&. Examples are \fIloglevel\fR, \fIcertfiles\fR and \fIlisten\fR\&. It is a configuration mistake to put \fIglobal\fR options under \fIhost_config\fR or \fIappend_host_config\fR section \- ejabberd will refuse to load such configuration\&.
.sp
-It is not recommended to write ejabberd\&.yml from scratch\&. Instead it is better to start from "default" configuration file available at https://github\&.com/processone/ejabberd/blob/21\&.12/ejabberd\&.yml\&.example\&. Once you get ejabberd running you can start changing configuration options to meet your requirements\&.
+It is not recommended to write ejabberd\&.yml from scratch\&. Instead it is better to start from "default" configuration file available at https://github\&.com/processone/ejabberd/blob/25\&.08/ejabberd\&.yml\&.example\&. Once you get ejabberd running you can start changing configuration options to meet your requirements\&.
.sp
Note that this document is intended to provide comprehensive description of all configuration options that can be consulted to understand the meaning of a particular option, its format and possible values\&. It will be quite hard to understand how to configure ejabberd by reading this document only \- for this purpose the reader is recommended to read online Configuration Guide available at https://docs\&.ejabberd\&.im/admin/configuration\&.
.SH "TOP LEVEL OPTIONS"
.sp
-This section describes top level options of ejabberd\&.
+This section describes top level options of ejabberd 25\&.08\&. The options that changed in this version are marked with 🟤\&.
.PP
-\fBaccess_rules\fR: \fI{AccessName: {allow|deny: ACLRules|ACLName}}\fR
+\fBaccess_rules\fR: \fI{AccessName: {allow|deny: ACLName|ACLDefinition}}\fR
.RS 4
-The option specifies access rules\&. Each access rule is assigned a name that can be referenced from other parts of the configuration file (mostly from
+This option defines
+\fIbasic\&.md#access\-rules|Access Rules\fR\&. Each access rule is assigned a name that can be referenced from other parts of the configuration file (mostly from
\fIaccess\fR
options of ejabberd modules)\&. Each rule definition may contain arbitrary number of
\fIallow\fR
@@ -137,7 +138,8 @@ access_rules:
.PP
\fBacl\fR: \fI{ACLName: {ACLType: ACLValue}}\fR
.RS 4
-The option defines access control lists: named sets of rules which are used to match against different targets (such as a JID or an IP address)\&. Every set of rules has name
+This option defines
+\fI\&.\&./configuration/basic\&.md#acl|access control lists\fR: named sets of rules which are used to match against different targets (such as a JID or an IP address)\&. Every set of rules has name
\fIACLName\fR: it can be any string except
\fIall\fR
or
@@ -246,7 +248,7 @@ is in the form of "regexp", the rule matches any JID with node part matching reg
.PP
\fBacme\fR: \fIOptions\fR
.RS 4
-ACME
+\fIbasic\&.md#acme|ACME\fR
configuration, to automatically obtain SSL certificates for the domains served by ejabberd, which means that certificate requests and renewals are performed to some CA server (aka "ACME server") in a fully automated mode\&. The
\fIOptions\fR
are:
@@ -302,7 +304,9 @@ acme:
.PP
\fBallow_contrib_modules\fR: \fItrue | false\fR
.RS 4
-Whether to allow installation of third\-party modules or not\&. The default value is
+Whether to allow installation of third\-party modules or not\&. See
+\fI\&.\&./\&.\&./admin/guide/modules\&.md#ejabberd\-contrib|ejabberd\-contrib\fR
+documentation section\&. The default value is
\fItrue\fR\&.
.RE
.PP
@@ -316,7 +320,9 @@ means that the same username can be taken multiple times in anonymous login mode
.PP
\fBanonymous_protocol\fR: \fIlogin_anon | sasl_anon | both\fR
.RS 4
-Define what anonymous protocol will be used:
+Define what
+\fIauthentication\&.md#anonymous\-login\-and\-sasl\-anonymous|anonymous\fR
+protocol will be used:
.sp
.RS 4
.ie n \{\
@@ -360,16 +366,13 @@ The default value is \fIsasl_anon\fR\&.
\fBapi_permissions\fR: \fI[Permission, \&.\&.\&.]\fR
.RS 4
Define the permissions for API access\&. Please consult the ejabberd Docs web → For Developers → ejabberd ReST API →
-API Permissions\&.
+\fI\&.\&./\&.\&./developer/ejabberd\-api/permissions\&.md|API Permissions\fR\&.
.RE
.PP
\fBappend_host_config\fR: \fI{Host: Options}\fR
.RS 4
-To define specific ejabberd modules in a virtual host, you can define the global
-\fImodules\fR
-option with the common modules, and later add specific modules to certain virtual hosts\&. To accomplish that,
-\fIappend_host_config\fR
-option can be used\&.
+Add a few specific options to a certain
+\fI\&.\&./configuration/basic\&.md#virtual\-hosting|virtual host\fR\&.
.RE
.PP
\fBauth_cache_life_time\fR: \fItimeout()\fR
@@ -396,9 +399,22 @@ Same as
will be used\&.
.RE
.PP
+\fBauth_external_user_exists_check\fR: \fItrue | false\fR
+.RS 4
+\fINote\fR
+about this option: added in 23\&.10\&. Supplement check for user existence based on
+\fImod_last\fR
+data, for authentication methods that don\(cqt have a way to reliably tell if a user exists (like is the case for
+\fIjwt\fR
+and certificate based authentication)\&. This helps with processing offline message for those users\&. The default value is
+\fItrue\fR\&.
+.RE
+.PP
\fBauth_method\fR: \fI[mnesia | sql | anonymous | external | jwt | ldap | pam, \&.\&.\&.]\fR
.RS 4
-A list of authentication methods to use\&. If several methods are defined, authentication is considered successful as long as authentication of at least one of the methods succeeds\&. The default value is
+A list of
+\fIauthentication\&.md|authentication\fR
+methods to use\&. If several methods are defined, authentication is considered successful as long as authentication of at least one of the methods succeeds\&. The default value is
\fI[mnesia]\fR\&.
.RE
.PP
@@ -407,15 +423,16 @@ A list of authentication methods to use\&. If several methods are defined, authe
This is used by the contributed module
\fIejabberd_auth_http\fR
that can be installed from the
-ejabberd\-contrib
+\fI\&.\&./\&.\&./admin/guide/modules\&.md#ejabberd\-contrib|ejabberd\-contrib\fR
Git repository\&. Please refer to that module\(cqs README file for details\&.
.RE
-.sp
-\fINote\fR about the next option: improved in 20\&.01:
.PP
\fBauth_password_format\fR: \fIplain | scram\fR
.RS 4
-The option defines in what format the users passwords are stored:
+\fINote\fR
+about this option: improved in 20\&.01\&. The option defines in what format the users passwords are stored, plain text or in
+\fIauthentication\&.md#scram|SCRAM\fR
+format:
.sp
.RS 4
.ie n \{\
@@ -425,7 +442,7 @@ The option defines in what format the users passwords are stored:
.sp -1
.IP \(bu 2.3
.\}
-\fIplain\fR: The password is stored as plain text in the database\&. This is risky because the passwords can be read if your database gets compromised\&. This is the default value\&. This format allows clients to authenticate using: the old Jabber Non\-SASL (XEP\-0078), SASL PLAIN, SASL DIGEST\-MD5, and SASL SCRAM\-SHA\-1\&.
+\fIplain\fR: The password is stored as plain text in the database\&. This is risky because the passwords can be read if your database gets compromised\&. This is the default value\&. This format allows clients to authenticate using: the old Jabber Non\-SASL (XEP\-0078), SASL PLAIN, SASL DIGEST\-MD5, and SASL SCRAM\-SHA\-1/256/512(\-PLUS)\&.
.RE
.sp
.RS 4
@@ -436,17 +453,39 @@ The option defines in what format the users passwords are stored:
.sp -1
.IP \(bu 2.3
.\}
-\fIscram\fR: The password is not stored, only some information that allows to verify the hash provided by the client\&. It is impossible to obtain the original plain password from the stored information; for this reason, when this value is configured it cannot be changed to plain anymore\&. This format allows clients to authenticate using: SASL PLAIN and SASL SCRAM\-SHA\-1\&. The default value is
-\fIplain\fR\&.
+\fIscram\fR: The password is not stored, only some information required to verify the hash provided by the client\&. It is impossible to obtain the original plain password from the stored information; for this reason, when this value is configured it cannot be changed to plain anymore\&. This format allows clients to authenticate using: SASL PLAIN and SASL SCRAM\-SHA\-1/256/512(\-PLUS)\&. The SCRAM variant depends on the
+\fIauth_scram_hash\fR
+option\&.
.RE
.RE
+.sp
+The default value is \fIplain\fR\&.
+.PP
+\fBauth_password_types_hidden_in_sasl1\fR: \fI[plain | scram_sha1 | scram_sha256 | scram_sha512]\fR
+.RS 4
+\fINote\fR
+about this option: added in 25\&.07\&. List of password types that should not be offered in SASL1 authenticatication\&. Because SASL1, unlike SASL2, can\(cqt have list of available mechanisms tailored to individual user, it\(cqs possible that offered mechanisms will not be compatible with stored password, especially if new password type was added recently\&. This option allows disabling offering some mechanisms in SASL1, to a time until new password type will be available for all users\&.
+.RE
.PP
\fBauth_scram_hash\fR: \fIsha | sha256 | sha512\fR
.RS 4
-Hash algorith that should be used to store password in SCRAM format\&. You shouldn\(cqt change this if you already have passwords generated with a different algorithm \- users that have such passwords will not be able to authenticate\&. The default value is
+Hash algorithm that should be used to store password in
+\fIauthentication\&.md#scram|SCRAM\fR
+format\&. You shouldn\(cqt change this if you already have passwords generated with a different algorithm \- users that have such passwords will not be able to authenticate\&. The default value is
\fIsha\fR\&.
.RE
.PP
+\fBauth_stored_password_types\fR: \fI[plain | scram_sha1 | scram_sha256 | scram_sha512]\fR
+.RS 4
+\fINote\fR
+about this option: added in 25\&.03\&. List of password types that should be stored simultaneously for each user in database\&. When the user sets the account password, database will be updated to store the password in formats compatible with each type listed here\&. This can be used to migrate user passwords to a more secure format\&. If this option if set, it will override values set in
+\fIauth_scram_hash\fR
+and
+\fIauth_password_format\fR
+options\&. The default value is
+[]\&.
+.RE
+.PP
\fBauth_use_cache\fR: \fItrue | false\fR
.RS 4
Same as
@@ -462,9 +501,9 @@ Full path to a file containing one or more CA certificates in PEM format\&. All
field\&. There is no default value\&.
.RE
.sp
-You can use host_config to specify this option per\-vhost\&.
+You can use \fIhost_config\fR to specify this option per\-vhost\&.
.sp
-To set a specific file per listener, use the listener\(cqs cafile option\&. Please notice that \fIc2s_cafile\fR overrides the listener\(cqs \fIcafile\fR option\&.
+To set a specific file per listener, use the listener\(cqs \fIlisten\-options\&.md#cafile|cafile\fR option\&. Please notice that \fIc2s_cafile\fR overrides the listener\(cqs \fIcafile\fR option\&.
.PP
\fBc2s_ciphers\fR: \fI[Cipher, \&.\&.\&.]\fR
.RS 4
@@ -490,7 +529,8 @@ c2s_ciphers:
.PP
\fBc2s_dhfile\fR: \fIPath\fR
.RS 4
-Full path to a file containing custom DH parameters to use for c2s connections\&. Such a file could be created with the command "openssl dhparam \-out dh\&.pem 2048"\&. If this option is not specified, 2048\-bit MODP Group with 256\-bit Prime Order Subgroup will be used as defined in RFC5114 Section 2\&.3\&.
+Full path to a file containing custom DH parameters to use for c2s connections\&. Such a file could be created with the command
+\fI"openssl dhparam \-out dh\&.pem 2048"\fR\&. If this option is not specified, 2048\-bit MODP Group with 256\-bit Prime Order Subgroup will be used as defined in RFC5114 Section 2\&.3\&.
.RE
.PP
\fBc2s_protocol_options\fR: \fI[Option, \&.\&.\&.]\fR
@@ -525,7 +565,7 @@ Whether to enable or disable TLS compression for c2s connections\&. The default
Path to a file of CA root certificates\&. The default is to use system defined file if possible\&.
.RE
.sp
-For server conections, this \fIca_file\fR option is overriden by the s2s_cafile option\&.
+For server connections, this \fIca_file\fR option is overridden by the \fIs2s_cafile\fR option\&.
.PP
\fBcache_life_time\fR: \fItimeout()\fR
.RS 4
@@ -559,11 +599,32 @@ A maximum number of items (not memory!) in cache\&. The rule of thumb, for all t
\fIsm_cache_size\fR\&.
.RE
.PP
-\fBcaptcha_cmd\fR: \fIPath\fR
+\fBcaptcha_cmd\fR: \fIPath | ModuleName\fR
.RS 4
-Full path to a script that generates
-CAPTCHA
-images\&. There is no default value: when this option is not set, CAPTCHA functionality is completely disabled\&.
+\fINote\fR
+about this option: improved in 23\&.01\&. Full path to a script that generates
+\fIbasic\&.md#captcha|CAPTCHA\fR
+images\&. The keyword
+\fI@VERSION@\fR
+is replaced with ejabberd version number in
+\fIXX\&.YY\fR
+format\&. The keyword
+\fI@SEMVER@\fR
+is replaced with ejabberd version number in semver format when compiled with Elixir\(cqs mix, or XX\&.YY format otherwise\&. Alternatively, it can be the name of a module that implements ejabberd CAPTCHA support\&. There is no default value: when this option is not set, CAPTCHA functionality is completely disabled\&.
+.sp
+\fBExamples\fR:
+.sp
+When using the ejabberd installers or container image, the example captcha scripts can be used like this:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+captcha_cmd: /opt/ejabberd\-@VERSION@/lib/ejabberd\-@SEMVER@/priv/bin/captcha\&.sh
+.fi
+.if n \{\
+.RE
+.\}
.RE
.PP
\fBcaptcha_host\fR: \fIString\fR
@@ -576,20 +637,28 @@ instead\&.
\fBcaptcha_limit\fR: \fIpos_integer() | infinity\fR
.RS 4
Maximum number of
-CAPTCHA
+\fIbasic\&.md#captcha|CAPTCHA\fR
generated images per minute for any given JID\&. The option is intended to protect the server from CAPTCHA DoS\&. The default value is
\fIinfinity\fR\&.
.RE
.PP
-\fBcaptcha_url\fR: \fIURL\fR
+\fBcaptcha_url\fR: \fIURL | auto | undefined\fR
.RS 4
-An URL where
-CAPTCHA
+\fINote\fR
+about this option: improved in 23\&.04\&. An URL where
+\fIbasic\&.md#captcha|CAPTCHA\fR
requests should be sent\&. NOTE: you need to configure
\fIrequest_handlers\fR
for
\fIejabberd_http\fR
-listener as well\&. There is no default value\&.
+listener as well\&. If set to
+\fIauto\fR, it builds the URL using a
+\fIrequest_handler\fR
+already enabled, with encryption if available\&. If set to
+\fIundefined\fR, it builds the URL using the deprecated
+\fIcaptcha_host\fR
+\fI+ /captcha\fR\&. The default value is
+\fIauto\fR\&.
.RE
.PP
\fBcertfiles\fR: \fI[Path, \&.\&.\&.]\fR
@@ -601,6 +670,8 @@ and so on\&. NOTE: if you modify the certificate files or change the value of th
\fIejabberdctl reload\-config\fR
in order to rebuild and reload the certificate chains\&.
.sp
+\fBExamples\fR:
+.sp
If you use
Let\(cqs Encrypt
certificates for your domain "domain\&.tld", the configuration will look like this:
@@ -631,23 +702,55 @@ A list of Erlang nodes to connect on ejabberd startup\&. This option is mostly i
.PP
\fBdefault_db\fR: \fImnesia | sql\fR
.RS 4
-Default persistent storage for ejabberd\&. Modules and other components (e\&.g\&. authentication) may have its own value\&. The default value is
+\fIdatabase\&.md#default\-database|Default database\fR
+to store persistent data in ejabberd\&. Some components can be configured with specific toplevel options like
+\fIoauth_db_type\fR\&. Many modules can be configured with specific module options, usually named
+db_type\&. The default value is
\fImnesia\fR\&.
.RE
.PP
\fBdefault_ram_db\fR: \fImnesia | redis | sql\fR
.RS 4
-Default volatile (in\-memory) storage for ejabberd\&. Modules and other components (e\&.g\&. session management) may have its own value\&. The default value is
+Default volatile (in\-memory) storage for ejabberd\&. Some components can be configured with specific toplevel options like
+\fIrouter_db_type\fR
+and
+\fIsm_db_type\fR\&. Some modules can be configured with specific module options, usually named
+ram_db_type\&. The default value is
\fImnesia\fR\&.
.RE
.PP
-\fBdefine_macro\fR: \fI{MacroName: MacroValue}\fR
+\fBdefine_keyword\fR: \fI{NAME: Value}\fR
.RS 4
-Defines a macro\&. The value can be any valid arbitrary YAML value\&. For convenience, it\(cqs recommended to define a
-\fIMacroName\fR
-in capital letters\&. Duplicated macros are not allowed\&. Macros are processed after additional configuration files have been included, so it is possible to use macros that are defined in configuration files included before the usage\&. It is possible to use a
-\fIMacroValue\fR
-in the definition of another macro\&.
+\fINote\fR
+about this option: added in 25\&.03\&. Allows to define configuration
+\fI\&.\&./configuration/file\-format\&.md#macros\-and\-keywords|keywords\fR\&.
+.sp
+\fBExample\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+define_keyword:
+ SQL_USERNAME: "eja\&.global"
+
+host_config:
+ localhost:
+ define_keyword:
+ SQL_USERNAME: "eja\&.localhost"
+
+sql_username: "prefix\&.@SQL_USERNAME@"
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\fBdefine_macro\fR: \fI{NAME: Value}\fR
+.RS 4
+\fINote\fR
+about this option: improved in 25\&.03\&. Allows to define configuration
+\fI\&.\&./configuration/file\-format\&.md#macros\-and\-keywords|macros\fR\&.
.sp
\fBExample\fR:
.sp
@@ -681,9 +784,19 @@ or
is case\-insensitive\&. The default value is an empty list, i\&.e\&. no mechanisms are disabled by default\&.
.RE
.PP
+\fBdisable_sasl_scram_downgrade_protection\fR: \fItrue | false\fR
+.RS 4
+Allows to disable sending data required by
+\fIXEP\-0474: SASL SCRAM Downgrade Protection\fR\&. There are known buggy clients (like those that use strophejs 1\&.6\&.2) which will not be able to authenticatate when servers sends data from that specification\&. This options allows server to disable it to allow even buggy clients connects, but in exchange decrease MITM protection\&. The default value of this option is
+\fIfalse\fR
+which enables this extension\&.
+.RE
+.PP
\fBdomain_balancing\fR: \fI{Domain: Options}\fR
.RS 4
-An algorithm to load balance the components that are plugged on an ejabberd cluster\&. It means that you can plug one or several instances of the same component on each ejabberd node and that the traffic will be automatically distributed\&. The algorithm to deliver messages to the component(s) can be specified by this option\&. For any component connected as
+An algorithm to
+\fI\&.\&./guide/clustering\&.md#service\-load\-balancing|load\-balance\fR
+the components that are plugged on an ejabberd cluster\&. It means that you can plug one or several instances of the same component on each ejabberd node and that the traffic will be automatically distributed\&. The algorithm to deliver messages to the component(s) can be specified by this option\&. For any component connected as
\fIDomain\fR, available
\fIOptions\fR
are:
@@ -693,28 +806,43 @@ are:
The number of components to balance\&.
.RE
.PP
-\fBtype\fR: \fIrandom | source | destination | bare_source | bare_destination\fR
+\fBtype\fR: \fIValue\fR
.RS 4
-How to deliver stanzas to connected components:
-\fIrandom\fR
-\- an instance is chosen at random;
-\fIdestination\fR
-\- an instance is chosen by the full JID of the packet\(cqs
+How to deliver stanzas to connected components\&. The default value is
+\fIrandom\fR\&. Possible values:
+.RE
+.PP
+\fB\- bare_destination\fR
+.RS 4
+by the bare JID (without resource) of the packet\(cqs
\fIto\fR
-attribute;
-\fIsource\fR
-\- by the full JID of the packet\(cqs
+attribute
+.RE
+.PP
+\fB\- bare_source\fR
+.RS 4
+by the bare JID (without resource) of the packet\(cqs
\fIfrom\fR
-attribute;
-\fIbare_destination\fR
-\- by the the bare JID (without resource) of the packet\(cqs
+attribute is used
+.RE
+.PP
+\fB\- destination\fR
+.RS 4
+an instance is chosen by the full JID of the packet\(cqs
\fIto\fR
-attribute;
-\fIbare_source\fR
-\- by the bare JID (without resource) of the packet\(cqs
+attribute
+.RE
+.PP
+\fB\- random\fR
+.RS 4
+an instance is chosen at random
+.RE
+.PP
+\fB\- source\fR
+.RS 4
+by the full JID of the packet\(cqs
\fIfrom\fR
-attribute is used\&. The default value is
-\fIrandom\fR\&.
+attribute
.RE
.sp
\fBExample\fR:
@@ -762,18 +890,22 @@ Define the base URI when performing ReST requests\&. The default value is:
.PP
\fBextauth_pool_name\fR: \fIName\fR
.RS 4
-Define the pool name appendix, so the full pool name will be
+Define the pool name appendix in
+\fIauthentication\&.md#external\-script|external auth\fR, so the full pool name will be
\fIextauth_pool_Name\fR\&. The default value is the hostname\&.
.RE
.PP
\fBextauth_pool_size\fR: \fISize\fR
.RS 4
-The option defines the number of instances of the same external program to start for better load balancing\&. The default is the number of available CPU cores\&.
+The option defines the number of instances of the same
+\fIauthentication\&.md#external\-script|external auth\fR
+program to start for better load balancing\&. The default is the number of available CPU cores\&.
.RE
.PP
\fBextauth_program\fR: \fIPath\fR
.RS 4
-Indicate in this option the full path to the external authentication script\&. The script must be executable by ejabberd\&.
+Indicate in this option the full path to the
+\fIauthentication\&.md#external\-script|external authentication script\fR\&. The script must be executable by ejabberd\&.
.RE
.PP
\fBfqdn\fR: \fIDomain\fR
@@ -792,7 +924,8 @@ for backward compatibility\&.
.RS 4
The option is used to redefine
\fIOptions\fR
-for virtual host
+for
+\fI\&.\&./configuration/basic\&.md#virtual\-hosting|virtual host\fR
\fIHost\fR\&. In the example below LDAP authentication method will be used on virtual host
\fIdomain\&.tld\fR
and SQL method will be used on virtual host
@@ -823,16 +956,46 @@ host_config:
.PP
\fBhosts\fR: \fI[Domain1, Domain2, \&.\&.\&.]\fR
.RS 4
-The option defines a list containing one or more domains that
-\fIejabberd\fR
-will serve\&. This is a
+List of one or more
+\fI\&.\&./configuration/basic\&.md#host\-names|host names\fR
+(or domains) that ejabberd will serve\&. This is a
\fBmandatory\fR
option\&.
.RE
.PP
+\fBhosts_alias\fR: \fI{Alias: Host}\fR
+.RS 4
+\fINote\fR
+about this option: added in 25\&.07\&. Define aliases for existing vhosts managed by ejabberd\&. An alias may be a regexp expression\&. This option is only consulted by the
+\fIejabberd_http\fR
+listener\&.
+.sp
+\fBExample\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+hosts:
+ \- domain\&.tld
+ \- example\&.org
+
+hosts_alias:
+ xmpp\&.domain\&.tld: domain\&.tld
+ jabber\&.domain\&.tld: domain\&.tld
+ mytest\&.net: example\&.org
+ "exa*": example\&.org
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
\fBinclude_config_file\fR: \fI[Filename, \&.\&.\&.] | {Filename: Options}\fR
.RS 4
-Read additional configuration from
+Read and
+\fI\&.\&./configuration/file\-format\&.md#include\-additional\-files|include additional file\fR
+from
\fIFilename\fR\&. If the value is provided in
\fI{Filename: Options}\fR
format, the
@@ -852,9 +1015,20 @@ Disallows the usage of those options in the included file
.RE
.RE
.PP
+\fBinstall_contrib_modules\fR: \fI[Module, \&.\&.\&.]\fR
+.RS 4
+\fINote\fR
+about this option: added in 23\&.10\&. Modules to install from
+\fI\&.\&./\&.\&./admin/guide/modules\&.md#ejabberd\-contrib|ejabberd\-contrib\fR
+at start time\&. The default value is an empty list of modules:
+\fI[]\fR\&.
+.RE
+.PP
\fBjwt_auth_only_rule\fR: \fIAccessName\fR
.RS 4
-This ACL rule defines accounts that can use only this auth method, even if others are also defined in the ejabberd configuration file\&. In other words: if there are several auth methods enabled for this host (JWT, SQL, \&...), users that match this rule can only use JWT\&. The default value is
+This ACL rule defines accounts that can use only the
+\fIauthentication\&.md#jwt\-authentication|JWT\fR
+auth method, even if others are also defined in the ejabberd configuration file\&. In other words: if there are several auth methods enabled for this host (JWT, SQL, \&...), users that match this rule can only use JWT\&. The default value is
\fInone\fR\&.
.RE
.PP
@@ -862,18 +1036,24 @@ This ACL rule defines accounts that can use only this auth method, even if other
.RS 4
By default, the JID is defined in the
\fI"jid"\fR
-JWT field\&. This option allows to specify other JWT field name where the JID is defined\&.
+JWT field\&. In this option you can specify other
+\fIauthentication\&.md#jwt\-authentication|JWT\fR
+field name where the JID is defined\&.
.RE
.PP
\fBjwt_key\fR: \fIFilePath\fR
.RS 4
-Path to the file that contains the JWK Key\&. The default value is
+Path to the file that contains the
+\fIauthentication\&.md#jwt\-authentication|JWT\fR
+key\&. The default value is
\fIundefined\fR\&.
.RE
.PP
\fBlanguage\fR: \fILanguage\fR
.RS 4
-The option defines the default language of server strings that can be seen by XMPP clients\&. If an XMPP client does not possess
+Define the
+\fI\&.\&./configuration/basic\&.md#default\-language|default language\fR
+of server strings that can be seen by XMPP clients\&. If an XMPP client does not possess
\fIxml:lang\fR
attribute, the specified language is used\&. The default value is
\fI"en"\fR\&.
@@ -881,9 +1061,10 @@ attribute, the specified language is used\&. The default value is
.PP
\fBldap_backups\fR: \fI[Host, \&.\&.\&.]\fR
.RS 4
-A list of IP addresses or DNS names of LDAP backup servers\&. When no servers listed in
+A list of IP addresses or DNS names of LDAP backup servers (see
+\fI\&.\&./configuration/ldap\&.md#ldap\-connection|LDAP connection\fR)\&. When no servers listed in
\fIldap_servers\fR
-option are reachable, ejabberd will try to connect to these backup servers\&. The default is an empty list, i\&.e\&. no backup servers specified\&. WARNING: ejabberd doesn\(cqt try to reconnect back to the main servers when they become operational again, so the only way to restore these connections is to restart ejabberd\&. This limitation might be fixed in future releases\&.
+option are reachable, ejabberd connects to these backup servers\&. The default is an empty list, i\&.e\&. no backup servers specified\&. Please notice that ejabberd only connects to the next server when the existing connection is lost; it doesn\(cqt detect when a previously\-attempted server becomes available again\&.
.RE
.PP
\fBldap_base\fR: \fIBase\fR
@@ -900,10 +1081,23 @@ Whether to dereference aliases or not\&. The default value is
\fBldap_dn_filter\fR: \fI{Filter: FilterAttrs}\fR
.RS 4
This filter is applied on the results returned by the main filter\&. The filter performs an additional LDAP lookup to make the complete result\&. This is useful when you are unable to define all filter rules in
-\fIldap_filter\fR\&. You can define "%u", "%d", "%s" and "%D" pattern variables in
-\fIFilter\fR: "%u" is replaced by a user\(cqs part of the JID, "%d" is replaced by the corresponding domain (virtual host), all "%s" variables are consecutively replaced by values from the attributes in
+\fIldap_filter\fR\&. You can define
+\fI"%u"\fR,
+\fI"%d"\fR,
+\fI"%s"\fR
+and
+\fI"%D"\fR
+pattern variables in
+\fIFilter: "%u"\fR
+is replaced by a user\(cqs part of the JID,
+\fI"%d"\fR
+is replaced by the corresponding domain (virtual host), all
+\fI"%s"\fR
+variables are consecutively replaced by values from the attributes in
\fIFilterAttrs\fR
-and "%D" is replaced by Distinguished Name from the result set\&. There is no default value, which means the result is not filtered\&. WARNING: Since this filter makes additional LDAP lookups, use it only as the last resort: try to define all filter rules in
+and
+\fI"%D"\fR
+is replaced by Distinguished Name from the result set\&. There is no default value, which means the result is not filtered\&. WARNING: Since this filter makes additional LDAP lookups, use it only as the last resort: try to define all filter rules in
\fIldap_filter\fR
option if possible\&.
.sp
@@ -930,7 +1124,10 @@ Whether to encrypt LDAP connection using TLS or not\&. The default value is
\fBldap_filter\fR: \fIFilter\fR
.RS 4
An LDAP filter as defined in
-RFC4515\&. There is no default value\&. Example: "(&(objectClass=shadowAccount)(memberOf=XMPP Users))"\&. NOTE: don\(cqt forget to close brackets and don\(cqt use superfluous whitespaces\&. Also you must not use "uid" attribute in the filter because this attribute will be appended to the filter automatically\&.
+RFC4515\&. There is no default value\&. Example:
+\fI"(&(objectClass=shadowAccount)(memberOf=XMPP Users))"\fR\&. NOTE: don\(cqt forget to close brackets and don\(cqt use superfluous whitespaces\&. Also you must not use
+\fI"uid"\fR
+attribute in the filter because this attribute will be appended to the filter automatically\&.
.RE
.PP
\fBldap_password\fR: \fIPassword\fR
@@ -954,7 +1151,8 @@ Bind Distinguished Name\&. The default value is an empty string, which means "an
.PP
\fBldap_servers\fR: \fI[Host, \&.\&.\&.]\fR
.RS 4
-A list of IP addresses or DNS names of your LDAP servers\&. The default value is
+A list of IP addresses or DNS names of your LDAP servers (see
+\fI\&.\&./configuration/ldap\&.md#ldap\-connection|LDAP connection\fR)\&. ejabberd connects immediately to all of them, and reconnects infinitely if connection is lost\&. The default value is
\fI[localhost]\fR\&.
.RE
.PP
@@ -992,20 +1190,47 @@ LDAP attributes which hold a list of attributes to use as alternatives for getti
\fIAttr\fR
is an LDAP attribute which holds the user\(cqs part of the JID and
\fIAttrFormat\fR
-must contain one and only one pattern variable "%u" which will be replaced by the user\(cqs part of the JID\&. For example, "%u@example\&.org"\&. If the value is in the form of
+must contain one and only one pattern variable
+\fI"%u"\fR
+which will be replaced by the user\(cqs part of the JID\&. For example,
+\fI"%\fR\fIu@example\fR\fI\&.org"\fR\&. If the value is in the form of
\fI[Attr]\fR
then
\fIAttrFormat\fR
-is assumed to be "%u"\&.
+is assumed to be
+\fI"%u"\fR\&.
.RE
.PP
\fBlisten\fR: \fI[Options, \&.\&.\&.]\fR
.RS 4
The option for listeners configuration\&. See the
-Listen Modules
+\fIlisten\&.md|Listen Modules\fR
section for details\&.
.RE
.PP
+\fBlog_burst_limit_count\fR: \fINumber\fR
+.RS 4
+\fINote\fR
+about this option: added in 22\&.10\&. The number of messages to accept in
+log_burst_limit_window_time
+period before starting to drop them\&. Default
+500
+.RE
+.PP
+\fBlog_burst_limit_window_time\fR: \fINumber\fR
+.RS 4
+\fINote\fR
+about this option: added in 22\&.10\&. The time period to rate\-limit log messages by\&. Defaults to
+1
+second\&.
+.RE
+.PP
+\fBlog_modules_fully\fR: \fI[Module, \&.\&.\&.]\fR
+.RS 4
+\fINote\fR
+about this option: added in 23\&.01\&. List of modules that will log everything independently from the general loglevel option\&.
+.RE
+.PP
\fBlog_rotate_count\fR: \fINumber\fR
.RS 4
The number of rotated log files to keep\&. The default value is
@@ -1019,14 +1244,14 @@ crash\&.log\&.0\&.
\fBlog_rotate_size\fR: \fIpos_integer() | infinity\fR
.RS 4
The size (in bytes) of a log file to trigger rotation\&. If set to
-\fIinfinity\fR, log rotation is disabled\&. The default value is
-\fI10485760\fR
-(that is, 10 Mb)\&.
+\fIinfinity\fR, log rotation is disabled\&. The default value is 10 Mb expressed in bytes:
+\fI10485760\fR\&.
.RE
.PP
\fBloglevel\fR: \fInone | emergency | alert | critical | error | warning | notice | info | debug\fR
.RS 4
-Verbosity of log files generated by ejabberd\&. The default value is
+Verbosity of ejabberd
+\fI\&.\&./configuration/basic\&.md#logging|logging\fR\&. The default value is
\fIinfo\fR\&. NOTE: previous versions of ejabberd had log levels defined in numeric format (\fI0\&.\&.5\fR)\&. The numeric values are still accepted for backward compatibility, but are not recommended\&.
.RE
.PP
@@ -1038,15 +1263,15 @@ This option specifies the maximum number of elements in the queue of the FSM (Fi
.PP
\fBmodules\fR: \fI{Module: Options}\fR
.RS 4
-The option for modules configuration\&. See
-Modules
-section for details\&.
+Set all the
+\fImodules\&.md|modules\fR
+configuration options\&.
.RE
.PP
\fBnegotiation_timeout\fR: \fItimeout()\fR
.RS 4
Time to wait for an XMPP stream negotiation to complete\&. When timeout occurs, the corresponding XMPP stream is closed\&. The default value is
-\fI30\fR
+\fI120\fR
seconds\&.
.RE
.PP
@@ -1059,12 +1284,11 @@ This option can be used to tune tick time parameter of
.PP
\fBnew_sql_schema\fR: \fItrue | false\fR
.RS 4
-Whether to use
+Whether to use the
+\fIdatabase\&.md#default\-and\-new\-schemas|new SQL schema\fR\&. All schemas are located at
+https://github\&.com/processone/ejabberd/tree/25\&.08/sql\&. There are two schemas available\&. The default legacy schema stores one XMPP domain into one ejabberd database\&. The
\fInew\fR
-SQL schema\&. All schemas are located at
-https://github\&.com/processone/ejabberd/tree/21\&.12/sql\&. There are two schemas available\&. The default legacy schema allows to store one XMPP domain into one ejabberd database\&. The
-\fInew\fR
-schema allows to handle several XMPP domains in a single ejabberd database\&. Using this
+schema can handle several XMPP domains in a single ejabberd database\&. Using this
\fInew\fR
schema is best when serving several XMPP domains and/or changing domains from time to time\&. This avoid need to manage several databases and handle complex configuration changes\&. The default depends on configuration flag
\fI\-\-enable\-new\-sql\-schema\fR
@@ -1095,12 +1319,11 @@ Same as
\fIcache_missed\fR
will be used\&.
.RE
-.sp
-\fINote\fR about the next option: added in 21\&.01:
.PP
\fBoauth_cache_rest_failure_life_time\fR: \fItimeout()\fR
.RS 4
-The time that a failure in OAuth ReST is cached\&. The default value is
+\fINote\fR
+about this option: added in 21\&.01\&. The time that a failure in OAuth ReST is cached\&. The default value is
\fIinfinity\fR\&.
.RE
.PP
@@ -1172,26 +1395,27 @@ option)\&. Later, when memory drops below this
percents\&.
.RE
.PP
-\fBoutgoing_s2s_families\fR: \fI[ipv4 | ipv6, \&.\&.\&.]\fR
+\fBoutgoing_s2s_families\fR: \fI[ipv6 | ipv4, \&.\&.\&.]\fR
.RS 4
-Specify which address families to try, in what order\&. The default is
-\fI[ipv4, ipv6]\fR
-which means it first tries connecting with IPv4, if that fails it tries using IPv6\&.
+\fINote\fR
+about this option: changed in 23\&.01\&. Specify which address families to try, in what order\&. The default is
+\fI[ipv6, ipv4]\fR
+which means it first tries connecting with IPv6, if that fails it tries using IPv4\&. This option is obsolete and irrelevant when using ejabberd 23\&.01 and Erlang/OTP 22, or newer versions of them\&.
.RE
-.sp
-\fINote\fR about the next option: added in 20\&.12:
.PP
\fBoutgoing_s2s_ipv4_address\fR: \fIAddress\fR
.RS 4
-Specify the IPv4 address that will be used when establishing an outgoing S2S IPv4 connection, for example "127\&.0\&.0\&.1"\&. The default value is
+\fINote\fR
+about this option: added in 20\&.12\&. Specify the IPv4 address that will be used when establishing an outgoing S2S IPv4 connection, for example
+\fI"127\&.0\&.0\&.1"\fR\&. The default value is
\fIundefined\fR\&.
.RE
-.sp
-\fINote\fR about the next option: added in 20\&.12:
.PP
\fBoutgoing_s2s_ipv6_address\fR: \fIAddress\fR
.RS 4
-Specify the IPv6 address that will be used when establishing an outgoing S2S IPv6 connection, for example "::FFFF:127\&.0\&.0\&.1"\&. The default value is
+\fINote\fR
+about this option: added in 20\&.12\&. Specify the IPv6 address that will be used when establishing an outgoing S2S IPv6 connection, for example
+\fI"::FFFF:127\&.0\&.0\&.1"\fR\&. The default value is
\fIundefined\fR\&.
.RE
.PP
@@ -1210,13 +1434,17 @@ seconds\&.
.PP
\fBpam_service\fR: \fIName\fR
.RS 4
-This option defines the PAM service name\&. Refer to the PAM documentation of your operation system for more information\&. The default value is
+This option defines the
+\fIauthentication\&.md#pam\-authentication|PAM\fR
+service name\&. Refer to the PAM documentation of your operation system for more information\&. The default value is
\fIejabberd\fR\&.
.RE
.PP
\fBpam_userinfotype\fR: \fIusername | jid\fR
.RS 4
-This option defines what type of information about the user ejabberd provides to the PAM service: only the username, or the user\(cqs JID\&. Default is
+This option defines what type of information about the user ejabberd provides to the
+\fIauthentication\&.md#pam\-authentication|PAM\fR
+service: only the username, or the user\(cqs JID\&. Default is
\fIusername\fR\&.
.RE
.PP
@@ -1250,36 +1478,47 @@ option where file queues will be placed\&. The default value is
.PP
\fBredis_connect_timeout\fR: \fItimeout()\fR
.RS 4
-A timeout to wait for the connection to be re\-established to the Redis server\&. The default is
+A timeout to wait for the connection to be re\-established to the
+\fIdatabase\&.md#redis|Redis\fR
+server\&. The default is
\fI1 second\fR\&.
.RE
.PP
\fBredis_db\fR: \fINumber\fR
.RS 4
-Redis database number\&. The default is
+\fIdatabase\&.md#redis|Redis\fR
+database number\&. The default is
\fI0\fR\&.
.RE
.PP
\fBredis_password\fR: \fIPassword\fR
.RS 4
-The password to the Redis server\&. The default is an empty string, i\&.e\&. no password\&.
+The password to the
+\fIdatabase\&.md#redis|Redis\fR
+server\&. The default is an empty string, i\&.e\&. no password\&.
.RE
.PP
\fBredis_pool_size\fR: \fINumber\fR
.RS 4
-The number of simultaneous connections to the Redis server\&. The default value is
+The number of simultaneous connections to the
+\fIdatabase\&.md#redis|Redis\fR
+server\&. The default value is
\fI10\fR\&.
.RE
.PP
\fBredis_port\fR: \fI1\&.\&.65535\fR
.RS 4
-The port where the Redis server is accepting connections\&. The default is
+The port where the
+\fIdatabase\&.md#redis|Redis\fR
+server is accepting connections\&. The default is
\fI6379\fR\&.
.RE
.PP
\fBredis_queue_type\fR: \fIram | file\fR
.RS 4
-The type of request queue for the Redis server\&. See description of
+The type of request queue for the
+\fIdatabase\&.md#redis|Redis\fR
+server\&. See description of
\fIqueue_type\fR
option for the explanation\&. The default value is the value defined in
\fIqueue_type\fR
@@ -1288,9 +1527,13 @@ or
if the latter is not set\&.
.RE
.PP
-\fBredis_server\fR: \fIHostname\fR
+\fBredis_server\fR: \fIHost | IP Address | Unix Socket Path\fR
.RS 4
-A hostname or an IP address of the Redis server\&. The default is
+\fINote\fR
+about this option: improved in 24\&.12\&. A hostname, IP address or unix domain socket file of the
+\fIdatabase\&.md#redis|Redis\fR
+server\&. Setup the path to unix domain socket like:
+\fI"unix:/path/to/socket"\fR\&. The default value is
\fIlocalhost\fR\&.
.RE
.PP
@@ -1310,6 +1553,30 @@ XMPP Core: section 7\&.7\&.2\&.2\&. The default value is
\fIcloseold\fR\&.
.RE
.PP
+\fBrest_proxy\fR: \fIHost\fR
+.RS 4
+\fINote\fR
+about this option: added in 25\&.07\&. Address of a HTTP Connect proxy used by modules issuing rest calls (like ejabberd_oauth_rest)
+.RE
+.PP
+\fBrest_proxy_password\fR: \fIstring()\fR
+.RS 4
+\fINote\fR
+about this option: added in 25\&.07\&. Password used to authenticate to HTTP Connect proxy used by modules issuing rest calls (like ejabberd_oauth_rest)
+.RE
+.PP
+\fBrest_proxy_port\fR: \fI1\&.\&.65535\fR
+.RS 4
+\fINote\fR
+about this option: added in 25\&.07\&. Port of a HTTP Connect proxy used by modules issuing rest calls (like ejabberd_oauth_rest)
+.RE
+.PP
+\fBrest_proxy_username\fR: \fIstring()\fR
+.RS 4
+\fINote\fR
+about this option: added in 25\&.07\&. Username used to authenticate to HTTP Connect proxy used by modules issuing rest calls (like ejabberd_oauth_rest)
+.RE
+.PP
\fBrouter_cache_life_time\fR: \fItimeout()\fR
.RS 4
Same as
@@ -1360,19 +1627,20 @@ seconds\&.
.PP
\fBs2s_access\fR: \fIAccess\fR
.RS 4
-The access rule to restrict server\-to\-server connections\&. The default value is
-\fIall\fR
-which means no restrictions are applied\&.
+This
+\fIbasic\&.md#access\-rules|Access Rule\fR
+defines to what remote servers can s2s connections be established\&. The default value is
+\fIall\fR; no restrictions are applied, it is allowed to connect s2s to/from all remote servers\&.
.RE
.PP
\fBs2s_cafile\fR: \fIPath\fR
.RS 4
A path to a file with CA root certificates that will be used to authenticate s2s connections\&. If not set, the value of
-ca_file
+\fIca_file\fR
will be used\&.
.RE
.sp
-You can use host_config to specify this option per\-vhost\&.
+You can use \fIhost_config\fR to specify this option per\-vhost\&.
.PP
\fBs2s_ciphers\fR: \fI[Cipher, \&.\&.\&.]\fR
.RS 4
@@ -1398,7 +1666,8 @@ s2s_ciphers:
.PP
\fBs2s_dhfile\fR: \fIPath\fR
.RS 4
-Full path to a file containing custom DH parameters to use for s2s connections\&. Such a file could be created with the command "openssl dhparam \-out dh\&.pem 2048"\&. If this option is not specified, 2048\-bit MODP Group with 256\-bit Prime Order Subgroup will be used as defined in RFC5114 Section 2\&.3\&.
+Full path to a file containing custom DH parameters to use for s2s connections\&. Such a file could be created with the command
+\fI"openssl dhparam \-out dh\&.pem 2048"\fR\&. If this option is not specified, 2048\-bit MODP Group with 256\-bit Prime Order Subgroup will be used as defined in RFC5114 Section 2\&.3\&.
.RE
.PP
\fBs2s_dns_retries\fR: \fINumber\fR
@@ -1456,7 +1725,8 @@ if the latter is not set\&.
\fBs2s_timeout\fR: \fItimeout()\fR
.RS 4
A time to wait before closing an idle s2s connection\&. The default value is
-\fI10 minutes\fR\&.
+\fI1\fR
+hour\&.
.RE
.PP
\fBs2s_tls_compression\fR: \fItrue | false\fR
@@ -1491,7 +1761,8 @@ XEP\-0138) or not\&. The default value is
.PP
\fBshaper\fR: \fI{ShaperName: Rate}\fR
.RS 4
-The option defines a set of shapers\&. Every shaper is assigned a name
+The option defines a set of
+\fI\&.\&./configuration/basic\&.md#shapers|shapers\fR\&. Every shaper is assigned a name
\fIShaperName\fR
that can be used in other parts of the configuration file, such as
\fIshaper_rules\fR
@@ -1521,9 +1792,11 @@ shaper:
.\}
.RE
.PP
-\fBshaper_rules\fR: \fI{ShaperRuleName: {Number|ShaperName: ACLRule|ACLName}}\fR
+\fBshaper_rules\fR: \fI{ShaperRuleName: {Number|ShaperName: ACLName|ACLDefinition}}\fR
.RS 4
-An entry allowing to declaring shaper to use for matching user/hosts\&. Semantics is similar to
+This option defines
+\fI\&.\&./configuration/basic\&.md#shaper\-rules|shaper rules\fR
+to use for matching user/hosts\&. Semantics is similar to
\fIaccess_rules\fR
option, the only difference is that instead using
\fIallow\fR
@@ -1609,19 +1882,29 @@ An SQL database name\&. For SQLite this must be a full path to a database file\&
\fIejabberd\fR\&.
.RE
.PP
+\fBsql_flags\fR: \fI[mysql_alternative_upsert]\fR
+.RS 4
+\fINote\fR
+about this option: added in 24\&.02\&. This option accepts a list of SQL flags, and is empty by default\&.
+\fImysql_alternative_upsert\fR
+forces the alternative upsert implementation in MySQL\&.
+.RE
+.PP
\fBsql_keepalive_interval\fR: \fItimeout()\fR
.RS 4
An interval to make a dummy SQL request to keep alive the connections to the database\&. There is no default value, so no keepalive requests are made\&.
.RE
-.sp
-\fINote\fR about the next option: added in 20\&.12:
.PP
\fBsql_odbc_driver\fR: \fIPath\fR
.RS 4
-Path to the ODBC driver to use to connect to a Microsoft SQL Server database\&. This option is only valid if the
+\fINote\fR
+about this option: added in 20\&.12\&. Path to the ODBC driver to use to connect to a Microsoft SQL Server database\&. This option only applies if the
\fIsql_type\fR
option is set to
-\fImssql\fR\&. The default value is:
+\fImssql\fR
+and
+\fIsql_server\fR
+is not an ODBC connection string\&. The default value is:
\fIlibtdsodbc\&.so\fR
.RE
.PP
@@ -1632,7 +1915,8 @@ The password for SQL authentication\&. The default is empty string\&.
.PP
\fBsql_pool_size\fR: \fISize\fR
.RS 4
-Number of connections to the SQL server that ejabberd will open for each virtual host\&. The default value is 10\&. WARNING: for SQLite this value is
+Number of connections to the SQL server that ejabberd will open for each virtual host\&. The default value is
+\fI10\fR\&. WARNING: for SQLite this value is
\fI1\fR
by default and it\(cqs not recommended to change it due to potential race conditions\&.
.RE
@@ -1647,14 +1931,13 @@ for PostgreSQL and
\fI1433\fR
for MS SQL\&. The option has no effect for SQLite\&.
.RE
-.sp
-\fINote\fR about the next option: added in 20\&.01:
.PP
\fBsql_prepared_statements\fR: \fItrue | false\fR
.RS 4
-This option is
+\fINote\fR
+about this option: added in 20\&.01\&. This option is
\fItrue\fR
-by default, and is useful to disable prepared statements\&. The option is valid for PostgreSQL\&.
+by default, and is useful to disable prepared statements\&. The option is valid for PostgreSQL and MySQL\&.
.RE
.PP
\fBsql_query_timeout\fR: \fItimeout()\fR
@@ -1675,17 +1958,28 @@ or
if the latter is not set\&.
.RE
.PP
-\fBsql_server\fR: \fIHost\fR
+\fBsql_server\fR: \fIHost | IP Address | ODBC Connection String | Unix Socket Path\fR
.RS 4
-A hostname or an IP address of the SQL server\&. The default value is
+\fINote\fR
+about this option: improved in 24\&.06\&. The hostname or IP address of the SQL server\&. For
+\fIsql_type\fR
+\fImssql\fR
+or
+\fIodbc\fR
+this can also be an ODBC connection string\&. When
+\fIsql_type\fR
+is
+\fImysql\fR
+or
+\fIpgsql\fR, this can be the path to a unix domain socket expressed like:
+\fI"unix:/path/to/socket"\fR\&.The default value is
\fIlocalhost\fR\&.
.RE
-.sp
-\fINote\fR about the next option: improved in 20\&.03:
.PP
\fBsql_ssl\fR: \fItrue | false\fR
.RS 4
-Whether to use SSL encrypted connections to the SQL server\&. The option is only available for MySQL and PostgreSQL\&. The default value is
+\fINote\fR
+about this option: improved in 20\&.03\&. Whether to use SSL encrypted connections to the SQL server\&. The option is only available for MySQL, MS SQL and PostgreSQL\&. The default value is
\fIfalse\fR\&.
.RE
.PP
@@ -1696,7 +1990,7 @@ A path to a file with CA root certificates that will be used to verify SQL conne
and
\fIsql_ssl_verify\fR
options are set to
-\fItrue\fR\&. There is no default which means certificate verification is disabled\&.
+\fItrue\fR\&. There is no default which means certificate verification is disabled\&. This option has no effect for MS SQL\&.
.RE
.PP
\fBsql_ssl_certfile\fR: \fIPath\fR
@@ -1704,7 +1998,7 @@ options are set to
A path to a certificate file that will be used for SSL connections to the SQL server\&. Implies
\fIsql_ssl\fR
option is set to
-\fItrue\fR\&. There is no default which means ejabberd won\(cqt provide a client certificate to the SQL server\&.
+\fItrue\fR\&. There is no default which means ejabberd won\(cqt provide a client certificate to the SQL server\&. This option has no effect for MS SQL\&.
.RE
.PP
\fBsql_ssl_verify\fR: \fItrue | false\fR
@@ -1714,7 +2008,7 @@ Whether to verify SSL connection to the SQL server against CA root certificates
option\&. Implies
\fIsql_ssl\fR
option is set to
-\fItrue\fR\&. The default value is
+\fItrue\fR\&. This option has no effect for MS SQL\&. The default value is
\fIfalse\fR\&.
.RE
.PP
@@ -1742,12 +2036,25 @@ A user name for SQL authentication\&. The default value is
Specify what proxies are trusted when an HTTP request contains the header
\fIX\-Forwarded\-For\fR\&. You can specify
\fIall\fR
-to allow all proxies, or specify a list of IPs, possibly with masks\&. The default value is an empty list\&. This allows, if enabled, to be able to know the real IP of the request, for admin purpose, or security configuration (for example using
+to allow all proxies, or specify a list of IPs, possibly with masks\&. The default value is an empty list\&. Using this option you can know the real IP of the request, for admin purpose, or security configuration (for example using
\fImod_fail2ban\fR)\&. IMPORTANT: The proxy MUST be configured to set the
\fIX\-Forwarded\-For\fR
header if you enable this option as, otherwise, the client can set it itself and as a result the IP value cannot be trusted for security rules in ejabberd\&.
.RE
.PP
+\fBupdate_sql_schema\fR: \fItrue | false\fR
+.RS 4
+\fINote\fR
+about this option: updated in 24\&.06\&. Allow ejabberd to update SQL schema in MySQL, PostgreSQL and SQLite databases\&. This option was added in ejabberd 23\&.10, and enabled by default since 24\&.06\&. The default value is
+\fItrue\fR\&.
+.RE
+.PP
+\fBupdate_sql_schema_timeout\fR: \fItimeout()\fR
+.RS 4
+\fINote\fR
+about this option: added in 24\&.07\&. Time allocated to SQL schema update queries\&. The default value is set to 5 minutes\&.
+.RE
+.PP
\fBuse_cache\fR: \fItrue | false\fR
.RS 4
Enable or disable cache\&. The default is
@@ -1776,15 +2083,16 @@ module\&. The default value is obtained at compile time from the underlying vers
.RS 4
This option enables validation for
\fIOrigin\fR
-header to protect against connections from other domains than given in the configuration file\&. In this way, the lower layer load balancer can be chosen for a specific ejabberd implementation while still providing a secure Websocket connection\&. The default value is
+header to protect against connections from other domains than given in the configuration file\&. In this way, the lower layer load balancer can be chosen for a specific ejabberd implementation while still providing a secure WebSocket connection\&. The default value is
\fIignore\fR\&. An example value of the
\fIURL\fR
-is "https://test\&.example\&.org:8081"\&.
+is
+\fI"https://test\&.example\&.org:8081"\fR\&.
.RE
.PP
\fBwebsocket_ping_interval\fR: \fItimeout()\fR
.RS 4
-Defines time between pings sent by the server to a client (Websocket level protocol pings are used for this) to keep a connection active\&. If the client doesn\(cqt respond to two consecutive pings, the connection will be assumed as closed\&. The value of
+Defines time between pings sent by the server to a client (WebSocket level protocol pings are used for this) to keep a connection active\&. If the client doesn\(cqt respond to two consecutive pings, the connection will be assumed as closed\&. The value of
\fI0\fR
can be used to disable the feature\&. This option makes the server sending pings only for connections using the RFC compliant protocol\&. For older style connections the server expects that whitespace pings would be used for this purpose\&. The default value is
\fI60\fR
@@ -1799,9 +2107,13 @@ seconds\&.
.RE
.SH "MODULES"
.sp
-This section describes options of all ejabberd modules\&.
+This section describes modules options of ejabberd 25\&.08\&. The modules that changed in this version are marked with 🟤\&.
.SS "mod_adhoc"
.sp
+def:ad\-hoc command
+.sp
+: Command that can be executed by an XMPP client using XEP\-0050\&.
+.sp
This module implements XEP\-0050: Ad\-Hoc Commands\&. It\(cqs an auxiliary module and is only needed by some of the other modules\&.
.sp
.it 1 an-trap
@@ -1818,45 +2130,74 @@ Provide the Commands item in the Service Discovery\&. Default value:
\fIfalse\fR\&.
.RE
.RE
+.SS "mod_adhoc_api"
+.sp
+\fINote\fR about this option: added in 25\&.03\&.
+.sp
+Execute (def:API commands) in a XMPP client using XEP\-0050: Ad\-Hoc Commands\&. This module requires \fImod_adhoc\fR (to execute the commands), and recommends \fImod_disco\fR (to discover the commands)\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBAvailable options:\fR
+.RS 4
+.PP
+\fBdefault_version\fR: \fIinteger() | string()\fR
+.RS 4
+What API version to use\&. If setting an ejabberd version, it will use the latest API version that was available in that (def:c2s) ejabberd version\&. For example, setting
+\fI"24\&.06"\fR
+in this option implies
+\fI2\fR\&. The default value is the latest version\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBExample:\fR
+.RS 4
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+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
+.fi
+.if n \{\
+.RE
+.\}
+.RE
.SS "mod_admin_extra"
.sp
This module provides additional administrative commands\&.
.sp
Details for some commands:
.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-\fIban\-acount\fR: This command kicks all the connected sessions of the account from the server\&. It also changes their password to a randomly generated one, so they can\(cqt login anymore unless a server administrator changes their password again\&. It is possible to define the reason of the ban\&. The new password also includes the reason and the date and time of the ban\&. See an example below\&.
-.RE
+\fIban_account\fR API: This command kicks all the connected sessions of the account from the server\&. It also changes their password to a randomly generated one, so they can\(cqt login anymore unless a server administrator changes their password again\&. It is possible to define the reason of the ban\&. The new password also includes the reason and the date and time of the ban\&. See an example below\&.
.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-\fIpushroster\fR: (and
-\fIpushroster\-all\fR) The roster file must be placed, if using Windows, on the directory where you installed ejabberd: C:/Program Files/ejabberd or similar\&. If you use other Operating System, place the file on the same directory where the \&.beam files are installed\&. See below an example roster file\&.
-.RE
+\fIpush_roster\fR API (and \fIpush_roster_all\fR API): The roster file must be placed, if using Windows, on the directory where you installed ejabberd: C:/Program Files/ejabberd or similar\&. If you use other Operating System, place the file on the same directory where the \&.beam files are installed\&. See below an example roster file\&.
.sp
-.RS 4
-.ie n \{\
-\h'-04'\(bu\h'+03'\c
-.\}
-.el \{\
-.sp -1
-.IP \(bu 2.3
-.\}
-\fIsrg\-create\fR: If you want to put a group Name with blankspaces, use the characters "\*(Aq and \*(Aq" to define when the Name starts and ends\&. See an example below\&.
-.RE
+\fIsrg_create\fR API: If you want to put a group Name with blank spaces, use the characters \fI"\fR\*(Aq and \fI\*(Aq"\fR to define when the Name starts and ends\&. See an example below\&.
.sp
The module has no options\&.
.sp
@@ -1889,7 +2230,7 @@ modules:
.RE
.\}
.sp
-Content of roster file for \fIpushroster\fR command:
+Content of roster file for \fIpush_roster\fR API:
.sp
.if n \{\
.RS 4
@@ -1903,44 +2244,60 @@ Content of roster file for \fIpushroster\fR command:
.RE
.\}
.sp
-With this call, the sessions of the local account which JID is boby@example\&.org will be kicked, and its password will be set to something like \fIBANNED_ACCOUNT\(em20080425T21:45:07\(em2176635\(emSpammed_rooms\fR
+With this call, the sessions of the local account which JID is \fIboby@example\&.org\fR will be kicked, and its password will be set to something like \fIBANNED_ACCOUNT\(em20080425T21:45:07\(em2176635\(emSpammed_rooms\fR
.sp
.if n \{\
.RS 4
.\}
.nf
-ejabberdctl vhost example\&.org ban\-account boby "Spammed rooms"
+ejabberdctl vhost example\&.org ban_account boby "Spammed rooms"
.fi
.if n \{\
.RE
.\}
.sp
-Call to srg\-create using double\-quotes and single\-quotes:
+Call to \fIsrg_create\fR API using double\-quotes and single\-quotes:
.sp
.if n \{\
.RS 4
.\}
.nf
-ejabberdctl srg\-create g1 example\&.org "\*(AqGroup number 1\*(Aq" this_is_g1 g1
+ejabberdctl srg_create g1 example\&.org "\*(AqGroup number 1\*(Aq" this_is_g1 g1
.fi
.if n \{\
.RE
.\}
+.sp
+\fBAPI Tags:\fR \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#accounts|accounts\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#erlang|erlang\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#last|last\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#private|private\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#purge|purge\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#roster|roster\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#session|session\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#shared_roster_group|shared_roster_group\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#stanza|stanza\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#statistics|statistics\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#vcard|vcard\fR
.RE
.SS "mod_admin_update_sql"
.sp
-This module can be used to update existing SQL database from the default to the new schema\&. Check the section Default and New Schemas for details\&. Please note that only PostgreSQL is supported\&. When the module is loaded use \fIupdate_sql\fR API\&.
+This module can be used to update existing SQL database from the default to the new schema\&. Check the section \fIdatabase\&.md#default\-and\-new\-schemas|Default and New Schemas\fR for details\&. Please note that only MS SQL, MySQL, and PostgreSQL are supported\&. When the module is loaded use \fIupdate_sql\fR API\&.
.sp
The module has no options\&.
.SS "mod_announce"
.sp
-This module enables configured users to broadcast announcements and to set the message of the day (MOTD)\&. Configured users can perform these actions with an XMPP client either using Ad\-hoc Commands or sending messages to specific JIDs\&.
+This module enables configured users to broadcast announcements and to set the message of the day (MOTD)\&. Configured users can perform these actions with an XMPP client either using Ad\-Hoc Commands or sending messages to specific JIDs\&.
+.if n \{\
.sp
-Note that this module can be resource intensive on large deployments as it may broadcast a lot of messages\&. This module should be disabled for instances of ejabberd with hundreds of thousands users\&.
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
.sp
-The Ad\-hoc Commands are listed in the Server Discovery\&. For this feature to work, \fImod_adhoc\fR must be enabled\&.
+This module can be resource intensive on large deployments as it may broadcast a lot of messages\&. This module should be disabled for instances of ejabberd with hundreds of thousands users\&.
+.sp .5v
+.RE
.sp
-The specific JIDs where messages can be sent are listed below\&. The first JID in each entry will apply only to the specified virtual host example\&.org, while the JID between brackets will apply to all virtual hosts in ejabberd:
+To send announcements using XEP\-0050: Ad\-Hoc Commands, this module requires \fImod_adhoc\fR (to execute the commands), and recommends \fImod_disco\fR (to discover the commands)\&.
+.sp
+To send announcements by sending messages to specific JIDs, these are the destination JIDs:
.sp
.RS 4
.ie n \{\
@@ -1950,7 +2307,7 @@ The specific JIDs where messages can be sent are listed below\&. The first JID i
.sp -1
.IP \(bu 2.3
.\}
-example\&.org/announce/all (example\&.org/announce/all\-hosts/all):: The message is sent to all registered users\&. If the user is online and connected to several resources, only the resource with the highest priority will receive the message\&. If the registered user is not connected, the message will be stored offline in assumption that offline storage (see
+\fIexample\&.org/announce/all\fR: Send the message to all registered users in that vhost\&. If the user is online and connected to several resources, only the resource with the highest priority will receive the message\&. If the registered user is not connected, the message is stored offline in assumption that offline storage (see
\fImod_offline\fR) is enabled\&.
.RE
.sp
@@ -1962,7 +2319,7 @@ example\&.org/announce/all (example\&.org/announce/all\-hosts/all):: The message
.sp -1
.IP \(bu 2.3
.\}
-example\&.org/announce/online (example\&.org/announce/all\-hosts/online):: The message is sent to all connected users\&. If the user is online and connected to several resources, all resources will receive the message\&.
+\fIexample\&.org/announce/online\fR: Send the message to all connected users\&. If the user is online and connected to several resources, all resources will receive the message\&.
.RE
.sp
.RS 4
@@ -1973,7 +2330,8 @@ example\&.org/announce/online (example\&.org/announce/all\-hosts/online):: The m
.sp -1
.IP \(bu 2.3
.\}
-example\&.org/announce/motd (example\&.org/announce/all\-hosts/motd):: The message is set as the message of the day (MOTD) and is sent to users when they login\&. In addition the message is sent to all connected users (similar to announce/online)\&.
+\fIexample\&.org/announce/motd\fR: Set the message of the day (MOTD) that is sent to users when they login\&. Also sends the message to all connected users (similar to
+\fIannounce/online\fR)\&.
.RE
.sp
.RS 4
@@ -1984,7 +2342,7 @@ example\&.org/announce/motd (example\&.org/announce/all\-hosts/motd):: The messa
.sp -1
.IP \(bu 2.3
.\}
-example\&.org/announce/motd/update (example\&.org/announce/all\-hosts/motd/update):: The message is set as message of the day (MOTD) and is sent to users when they login\&. The message is not sent to any currently connected user\&.
+\fIexample\&.org/announce/motd/update\fR: Set the message of the day (MOTD) that is sent to users when they login\&. This does not send the message to any currently connected user\&.
.RE
.sp
.RS 4
@@ -1995,7 +2353,64 @@ example\&.org/announce/motd/update (example\&.org/announce/all\-hosts/motd/updat
.sp -1
.IP \(bu 2.3
.\}
-example\&.org/announce/motd/delete (example\&.org/announce/all\-hosts/motd/delete):: Any message sent to this JID removes the existing message of the day (MOTD)\&.
+\fIexample\&.org/announce/motd/delete\fR: Remove the existing message of the day (MOTD) by sending a message to this JID\&.
+.RE
+.sp
+There are similar destination JIDs to apply to all virtual hosts in ejabberd:
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fIexample\&.org/announce/all\-hosts/all\fR: send to all registered accounts
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fIexample\&.org/announce/all\-hosts/online\fR: send to online sessions
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fIexample\&.org/announce/all\-hosts/motd\fR: set MOTD and send to online
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fIexample\&.org/announce/all\-hosts/motd/update\fR: update MOTD
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+\fIexample\&.org/announce/all\-hosts/motd/delete\fR: delete MOTD
.RE
.sp
.it 1 an-trap
@@ -2048,6 +2463,186 @@ Same as top\-level
option, but applied to this module only\&.
.RE
.RE
+.SS "mod_antispam"
+.sp
+\fINote\fR about this option: added in 25\&.07\&.
+.sp
+Filter spam messages and subscription requests received from remote servers based on Real\-Time Block Lists (RTBL), lists of known spammer JIDs and/or URLs mentioned in spam messages\&. Traffic classified as spam is rejected with an error (and an \fI[info]\fR message is logged) unless the sender is subscribed to the recipient\(cqs presence\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBAvailable options:\fR
+.RS 4
+.PP
+\fBaccess_spam\fR: \fIAccess\fR
+.RS 4
+Access rule that controls what accounts may receive spam messages\&. If the rule returns
+\fIallow\fR
+for a given recipient, spam messages aren\(cqt rejected for that recipient\&. The default value is
+\fInone\fR, which means that all recipients are subject to spam filtering verification\&.
+.RE
+.PP
+\fBcache_size\fR: \fIpos_integer()\fR
+.RS 4
+Maximum number of JIDs that will be cached due to sending spam URLs\&. If that limit is exceeded, the least recently used entries are removed from the cache\&. Setting this option to
+\fI0\fR
+disables the caching feature\&. Note that separate caches are used for each virtual host, and that the caches aren\(cqt distributed across cluster nodes\&. The default value is
+\fI10000\fR\&.
+.RE
+.PP
+\fBrtbl_services\fR: \fI[Service]\fR
+.RS 4
+Query a RTBL service to get domains to block, as provided by
+xmppbl\&.org\&. Please note right now this option only supports one service in that list\&. For blocking spam and abuse on MUC channels, please use
+\fImod_muc_rtbl\fR
+for now\&. If only the host is provided, the default node names will be assumed\&. If the node name is different than
+\fIspam_source_domains\fR, you can setup the custom node name with the option
+\fIspam_source_domains_node\fR\&. The default value is an empty list of services\&.
+.sp
+\fBExample\fR:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+rtbl_services:
+ \- pubsub\&.server1\&.localhost:
+ spam_source_domains_node: actual_custom_pubsub_node
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.PP
+\fBspam_domains_file\fR: \fInone | Path\fR
+.RS 4
+Path to a plain text file containing a list of known spam domains, one domain per line\&. Messages and subscription requests sent from one of the listed domains are classified as spam if sender is not in recipient\(cqs roster\&. This list of domains gets merged with the one retrieved by an RTBL host if any given\&. Use an absolute path, or the
+\fI@CONFIG_PATH@\fR
+predefined keyword
+if the file is available in the configuration directory\&. The default value is
+\fInone\fR\&.
+.RE
+.PP
+\fBspam_dump_file\fR: \fIfalse | true | Path\fR
+.RS 4
+Path to the file to store blocked messages\&. Use an absolute path, or the
+\fI@LOG_PATH@\fR
+predefined keyword
+to store logs in the same place that the other ejabberd log files\&. If set to
+\fIfalse\fR, it doesn\(cqt dump stanzas, which is the default\&. If set to
+\fItrue\fR, it stores in
+\fI"@LOG_PATH@/spam_dump_@HOST@\&.log"\fR\&.
+.RE
+.PP
+\fBspam_jids_file\fR: \fInone | Path\fR
+.RS 4
+Path to a plain text file containing a list of known spammer JIDs, one JID per line\&. Messages and subscription requests sent from one of the listed JIDs are classified as spam\&. Messages containing at least one of the listed JIDsare classified as spam as well\&. Furthermore, the sender\(cqs JID will be cached, so that future traffic originating from that JID will also be classified as spam\&. Use an absolute path, or the
+\fI@CONFIG_PATH@\fR
+predefined keyword
+if the file is available in the configuration directory\&. The default value is
+\fInone\fR\&.
+.RE
+.PP
+\fBspam_urls_file\fR: \fInone | Path\fR
+.RS 4
+Path to a plain text file containing a list of URLs known to be mentioned in spam message bodies\&. Messages containing at least one of the listed URLs are classified as spam\&. Furthermore, the sender\(cqs JID will be cached, so that future traffic originating from that JID will be classified as spam as well\&. Use an absolute path, or the
+\fI@CONFIG_PATH@\fR
+predefined keyword
+if the file is available in the configuration directory\&. The default value is
+\fInone\fR\&.
+.RE
+.PP
+\fBwhitelist_domains_file\fR: \fInone | Path\fR
+.RS 4
+Path to a file containing a list of domains to whitelist from being blocked, one per line\&. If either it is in
+\fIspam_domains_file\fR
+or more realistically in a domain sent by a RTBL host (see option
+\fIrtbl_services\fR) then this domain will be ignored and stanzas from there won\(cqt be blocked\&. Use an absolute path, or the
+\fI@CONFIG_PATH@\fR
+predefined keyword
+if the file is available in the configuration directory\&. The default value is
+\fInone\fR\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBExample:\fR
+.RS 4
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+modules:
+ mod_antispam:
+ rtbl_services:
+ \- xmppbl\&.org
+ spam_jids_file: "@CONFIG_PATH@/spam_jids\&.txt"
+ spam_dump_file: "@LOG_PATH@/spam/host\-@HOST@\&.log"
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.SS "mod_auth_fast"
+.sp
+\fINote\fR about this option: added in 24\&.12\&.
+.sp
+The module adds support for XEP\-0484: Fast Authentication Streamlining Tokens that allows users to authenticate using self\-managed tokens\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBAvailable options:\fR
+.RS 4
+.PP
+\fBdb_type\fR: \fImnesia\fR
+.RS 4
+Same as top\-level
+\fIdefault_db\fR
+option, but applied to this module only\&.
+.RE
+.PP
+\fBtoken_lifetime\fR: \fItimeout()\fR
+.RS 4
+Time that tokens will be kept, measured from it\(cqs creation time\&. Default value set to 30 days
+.RE
+.PP
+\fBtoken_refresh_age\fR: \fItimeout()\fR
+.RS 4
+This time determines age of token, that qualifies for automatic refresh\&. Default value set to 1 day
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBExample:\fR
+.RS 4
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+modules:
+ mod_auth_fast:
+ token_lifetime: 14days
+.fi
+.if n \{\
+.RE
+.\}
+.RE
.SS "mod_avatar"
.sp
The purpose of the module is to cope with legacy and modern XMPP clients posting avatars\&. The process is described in XEP\-0398: User Avatar to vCard\-Based Avatars Conversion\&.
@@ -2066,7 +2661,7 @@ The module depends on \fImod_vcard\fR, \fImod_vcard_xupdate\fR and \fImod_pubsub
.PP
\fBconvert\fR: \fI{From: To}\fR
.RS 4
-Defines image convertion rules: the format in
+Defines image conversion rules: the format in
\fIFrom\fR
will be converted to format in
\fITo\fR\&. The value of
@@ -2091,13 +2686,13 @@ convert:
.PP
\fBrate_limit\fR: \fINumber\fR
.RS 4
-Limit any given JID by the number of avatars it is able to convert per minute\&. This is to protect the server from image convertion DoS\&. The default value is
+Limit any given JID by the number of avatars it is able to convert per minute\&. This is to protect the server from image conversion DoS\&. The default value is
\fI10\fR\&.
.RE
.RE
.SS "mod_block_strangers"
.sp
-This module allows to block/log messages coming from an unknown entity\&. If a writing entity is not in your roster, you can let this module drop and/or log the message\&. By default you\(cqll just not receive message from that entity\&. Enable this module if you want to drop SPAM messages\&.
+This module blocks and logs any messages coming from an unknown entity\&. If a writing entity is not in your roster, you can let this module drop and/or log the message\&. By default you\(cqll just not receive message from that entity\&. Enable this module if you want to drop SPAM messages\&.
.sp
.it 1 an-trap
.nr an-no-space-flag 1
@@ -2138,7 +2733,7 @@ and some server\(cqs JID is in user\(cqs roster, then messages from any user of
\fBcaptcha\fR: \fItrue | false\fR
.RS 4
Whether to generate CAPTCHA or not in response to messages from strangers\&. See also section
-CAPTCHA
+\fIbasic\&.md#captcha|CAPTCHA\fR
of the Configuration Guide\&. The default value is
\fIfalse\fR\&.
.RE
@@ -2164,7 +2759,7 @@ This module depends on \fImod_privacy\fR where all the configuration is performe
The module has no options\&.
.SS "mod_bosh"
.sp
-This module implements XMPP over BOSH as defined in XEP\-0124 and XEP\-0206\&. BOSH stands for Bidirectional\-streams Over Synchronous HTTP\&. It makes it possible to simulate long lived connections required by XMPP over the HTTP protocol\&. In practice, this module makes it possible to use XMPP in a browser without Websocket support and more generally to have a way to use XMPP while having to get through an HTTP proxy\&.
+This module implements XMPP over BOSH as defined in XEP\-0124 and XEP\-0206\&. BOSH stands for Bidirectional\-streams Over Synchronous HTTP\&. It makes it possible to simulate long lived connections required by XMPP over the HTTP protocol\&. In practice, this module makes it possible to use XMPP in a browser without WebSocket support and more generally to have a way to use XMPP while having to get through an HTTP proxy\&.
.sp
.it 1 an-trap
.nr an-no-space-flag 1
@@ -2234,9 +2829,9 @@ option, but applied to this module only\&.
.PP
\fBram_db_type\fR: \fImnesia | sql | redis\fR
.RS 4
-Same as
+Same as top\-level
\fIdefault_ram_db\fR
-but applied to this module only\&.
+option, but applied to this module only\&.
.RE
.PP
\fBuse_cache\fR: \fItrue | false\fR
@@ -2363,18 +2958,45 @@ While a client is inactive, queue presence stanzas that indicate (un)availabilit
.RE
.SS "mod_configure"
.sp
-The module provides server configuration functionality via XEP\-0050: Ad\-Hoc Commands\&. This module requires \fImod_adhoc\fR to be loaded\&.
+The module provides server configuration functionalities using XEP\-0030: Service Discovery and XEP\-0050: Ad\-Hoc Commands:
.sp
-The module has no options\&.
-.SS "mod_conversejs"
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+List and discover outgoing s2s, online client sessions and all registered accounts
+.RE
.sp
-This module serves a simple page for the Converse XMPP web browser client\&.
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Most of the ad\-hoc commands defined in
+XEP\-0133: Service Administration
+.RE
.sp
-To use this module, in addition to adding it to the \fImodules\fR section, you must also enable it in \fIlisten\fR → \fIejabberd_http\fR → request_handlers\&.
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Additional custom ad\-hoc commands specific to ejabberd
+.RE
.sp
-You must also setup either the option \fIwebsocket_url\fR or \fIbosh_service_url\fR\&.
+This module requires \fImod_adhoc\fR (to execute the commands), and recommends \fImod_disco\fR (to discover the commands)\&.
.sp
-By default, the options \fIconversejs_css\fR and \fIconversejs_script\fR point to the public Converse\&.js client\&. Alternatively, you can host the client locally using \fImod_http_fileserver\fR\&.
+Please notice that all the ad\-hoc commands implemented by this module have an equivalent API Command that you can execute using \fImod_adhoc_api\fR or any other API frontend\&.
.sp
.it 1 an-trap
.nr an-no-space-flag 1
@@ -2384,29 +3006,11 @@ By default, the options \fIconversejs_css\fR and \fIconversejs_script\fR point t
\fBAvailable options:\fR
.RS 4
.PP
-\fBbosh_service_url\fR: \fIBoshURL\fR
+\fBaccess\fR: \fIAccessName\fR
.RS 4
-BOSH service URL to which Converse\&.js can connect to\&.
-.RE
-.PP
-\fBconversejs_css\fR: \fIURL\fR
-.RS 4
-Converse\&.js CSS URL\&.
-.RE
-.PP
-\fBconversejs_script\fR: \fIURL\fR
-.RS 4
-Converse\&.js main script URL\&.
-.RE
-.PP
-\fBdefault_domain\fR: \fIDomain\fR
-.RS 4
-Specify a domain to act as the default for user JIDs\&. The default value is the first domain defined in the ejabberd configuration file\&.
-.RE
-.PP
-\fBwebsocket_url\fR: \fIWebsocketURL\fR
-.RS 4
-A websocket URL to which Converse\&.js can connect to\&.
+\fINote\fR
+about this option: added in 25\&.03\&. This option defines which access rule will be used to control who is allowed to access the features provided by this module\&. The default value is
+\fIconfigure\fR\&.
.RE
.RE
.sp
@@ -2422,17 +3026,185 @@ A websocket URL to which Converse\&.js can connect to\&.
.RS 4
.\}
.nf
+acl:
+ admin:
+ user: sun@localhost
+
+access_rules:
+ configure:
+ allow: admin
+
+modules:
+ mod_configure:
+ access: configure
+.fi
+.if n \{\
+.RE
+.\}
+.RE
+.SS "mod_conversejs"
+.sp
+\fINote\fR about this option: improved in 25\&.07\&.
+.sp
+This module serves a simple page for the Converse XMPP web browser client\&.
+.sp
+To use this module, in addition to adding it to the \fImodules\fR section, you must also enable it in \fIlisten\fR → \fIejabberd_http\fR → \fIlisten\-options\&.md#request_handlers|request_handlers\fR\&.
+.sp
+Make sure either \fImod_bosh\fR or \fIlisten\&.md#ejabberd_http_ws|ejabberd_http_ws\fR are enabled in at least one \fIrequest_handlers\fR\&.
+.sp
+When \fIconversejs_css\fR and \fIconversejs_script\fR are \fIauto\fR, by default they point to the public Converse client\&.
+.sp
+This module is available since ejabberd 21\&.12\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBAvailable options:\fR
+.RS 4
+.PP
+\fBbosh_service_url\fR: \fIauto | BoshURL\fR
+.RS 4
+BOSH service URL to which Converse can connect to\&. The keyword
+\fI@HOST@\fR
+is replaced with the real virtual host name\&. If set to
+\fIauto\fR, it will build the URL of the first configured BOSH request handler\&. The default value is
+\fIauto\fR\&.
+.RE
+.PP
+\fBconversejs_css\fR: \fIauto | URL\fR
+.RS 4
+Converse CSS URL\&. The keyword
+\fI@HOST@\fR
+is replaced with the hostname\&. The default value is
+\fIauto\fR\&.
+.RE
+.PP
+\fBconversejs_options\fR: \fI{Name: Value}\fR
+.RS 4
+\fINote\fR
+about this option: added in 22\&.05\&. Specify additional options to be passed to Converse\&. See
+Converse configuration\&. Only boolean, integer and string values are supported; lists are not supported\&.
+.RE
+.PP
+\fBconversejs_plugins\fR: \fI[Filename]\fR
+.RS 4
+List of additional local files to include as scripts in the homepage\&. Please make sure those files are available in the path specified in
+\fIconversejs_resources\fR
+option, in subdirectory
+\fIplugins/\fR\&. If using the public Converse client, then
+\fI"libsignal"\fR
+gets replaced with the URL of the public library\&. The default value is
+\fI[]\fR\&.
+.RE
+.PP
+\fBconversejs_resources\fR: \fIPath\fR
+.RS 4
+\fINote\fR
+about this option: added in 22\&.05\&. Local path to the Converse files\&. If not set, the public Converse client will be used instead\&.
+.RE
+.PP
+\fBconversejs_script\fR: \fIauto | URL\fR
+.RS 4
+Converse main script URL\&. The keyword
+\fI@HOST@\fR
+is replaced with the hostname\&. The default value is
+\fIauto\fR\&.
+.RE
+.PP
+\fBdefault_domain\fR: \fIDomain\fR
+.RS 4
+Specify a domain to act as the default for user JIDs\&. The keyword
+\fI@HOST@\fR
+is replaced with the hostname\&. The default value is
+\fI@HOST@\fR\&.
+.RE
+.PP
+\fBwebsocket_url\fR: \fIauto | WebSocketURL\fR
+.RS 4
+A WebSocket URL to which Converse can connect to\&. The
+\fI@HOST@\fR
+keyword is replaced with the real virtual host name\&. If set to
+\fIauto\fR, it will build the URL of the first configured WebSocket request handler\&. The default value is
+\fIauto\fR\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBExamples:\fR
+.RS 4
+.sp
+Manually setup WebSocket url, and use the public Converse client:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
listen:
\-
port: 5280
module: ejabberd_http
+ request_handlers:
+ /bosh: mod_bosh
+ /websocket: ejabberd_http_ws
+ /conversejs: mod_conversejs
+
+modules:
+ mod_bosh: {}
+ mod_conversejs:
+ conversejs_plugins: ["libsignal"]
+ websocket_url: "ws://@HOST@:5280/websocket"
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Host Converse locally and let auto detection of WebSocket and Converse URLs:
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+listen:
+ \-
+ port: 443
+ module: ejabberd_http
+ tls: true
request_handlers:
/websocket: ejabberd_http_ws
/conversejs: mod_conversejs
modules:
mod_conversejs:
- websocket_url: "ws://example\&.org:5280/websocket"
+ conversejs_resources: "/home/ejabberd/conversejs\-x\&.y\&.z/package/dist"
+ conversejs_plugins: ["libsignal\-protocol\&.min\&.js"]
+ # File path is: /home/ejabberd/conversejs\-x\&.y\&.z/package/dist/plugins/libsignal\-protocol\&.min\&.js
+.fi
+.if n \{\
+.RE
+.\}
+.sp
+Configure some additional options for Converse
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+modules:
+ mod_conversejs:
+ websocket_url: auto
+ conversejs_options:
+ auto_away: 30
+ clear_cache_on_logout: true
+ i18n: "pt"
+ locked_domain: "@HOST@"
+ message_archiving: always
+ theme: dracula
.fi
.if n \{\
.RE
@@ -2526,7 +3298,6 @@ acl:
server: sat\-pubsub\&.example\&.org
modules:
- \&.\&.\&.
mod_delegation:
namespaces:
urn:xmpp:mam:1:
@@ -2675,18 +3446,106 @@ hour\&.
The number of C2S authentication failures to trigger the IP ban\&. The default value is
\fI20\fR\&.
.RE
+.sp
+\fBAPI Tags:\fR \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#accounts|accounts\fR
+.RE
+.SS "mod_host_meta"
+.sp
+\fINote\fR about this option: added in 22\&.05\&.
+.sp
+This module serves small \fIhost\-meta\fR files as described in XEP\-0156: Discovering Alternative XMPP Connection Methods\&.
+.sp
+To use this module, in addition to adding it to the \fImodules\fR section, you must also enable it in \fIlisten\fR → \fIejabberd_http\fR → \fIlisten\-options\&.md#request_handlers|request_handlers\fR\&.
+.sp
+Notice it only works if \fIlisten\&.md#ejabberd_http|ejabberd_http\fR has \fIlisten\-options\&.md#tls|tls\fR enabled\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBAvailable options:\fR
+.RS 4
+.PP
+\fBbosh_service_url\fR: \fIundefined | auto | BoshURL\fR
+.RS 4
+BOSH service URL to announce\&. The keyword
+\fI@HOST@\fR
+is replaced with the real virtual host name\&. If set to
+\fIauto\fR, it will build the URL of the first configured BOSH request handler\&. The default value is
+\fIauto\fR\&.
+.RE
+.PP
+\fBwebsocket_url\fR: \fIundefined | auto | WebSocketURL\fR
+.RS 4
+WebSocket URL to announce\&. The keyword
+\fI@HOST@\fR
+is replaced with the real virtual host name\&. If set to
+\fIauto\fR, it will build the URL of the first configured WebSocket request handler\&. The default value is
+\fIauto\fR\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBExample:\fR
+.RS 4
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+listen:
+ \-
+ port: 443
+ module: ejabberd_http
+ tls: true
+ request_handlers:
+ /bosh: mod_bosh
+ /ws: ejabberd_http_ws
+ /\&.well\-known/host\-meta: mod_host_meta
+ /\&.well\-known/host\-meta\&.json: mod_host_meta
+
+modules:
+ mod_bosh: {}
+ mod_host_meta:
+ bosh_service_url: "https://@HOST@:5443/bosh"
+ websocket_url: "wss://@HOST@:5443/ws"
+.fi
+.if n \{\
+.RE
+.\}
.RE
.SS "mod_http_api"
.sp
-This module provides a ReST API to call ejabberd commands using JSON data\&.
+This module provides a ReST interface to call \fI\&.\&./\&.\&./developer/ejabberd\-api/index\&.md|ejabberd API\fR commands using JSON data\&.
.sp
-To use this module, in addition to adding it to the \fImodules\fR section, you must also enable it in \fIlisten\fR → \fIejabberd_http\fR → request_handlers\&.
+To use this module, in addition to adding it to the \fImodules\fR section, you must also enable it in \fIlisten\fR → \fIejabberd_http\fR → \fIlisten\-options\&.md#request_handlers|request_handlers\fR\&.
.sp
-To use a specific API version N, when defining the URL path in the request_handlers, add a \fIvN\fR\&. For example: \fI/api/v2: mod_http_api\fR
+To use a specific API version N, when defining the URL path in the request_handlers, add a vN\&. For example: \fI/api/v2: mod_http_api\fR\&.
.sp
-To run a command, send a POST request to the corresponding URL: \fIhttp://localhost:5280/api/\fR
+To run a command, send a POST request to the corresponding URL: \fIhttp://localhost:5280/api/COMMAND\-NAME\fR
.sp
-The module has no options\&.
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBAvailable options:\fR
+.RS 4
+.PP
+\fBdefault_version\fR: \fIinteger() | string()\fR
+.RS 4
+\fINote\fR
+about this option: added in 24\&.12\&. What API version to use when none is specified in the URL path\&. If setting an ejabberd version, it will use the latest API version that was available in that ejabberd version\&. For example, setting
+\fI"24\&.06"\fR
+in this option implies
+\fI2\fR\&. The default value is the latest version\&.
+.RE
+.RE
.sp
.it 1 an-trap
.nr an-no-space-flag 1
@@ -2708,7 +3567,8 @@ listen:
/api: mod_http_api
modules:
- mod_http_api: {}
+ mod_http_api:
+ default_version: 2
.fi
.if n \{\
.RE
@@ -2799,25 +3659,20 @@ List of accounts that are allowed to use this service\&. Default value:
\fBExamples:\fR
.RS 4
.sp
-This example configuration will serve the files from the local directory \fI/var/www\fR in the address \fIhttp://example\&.org:5280/pub/archive/\fR\&. In this example a new content type \fIogg\fR is defined, \fIpng\fR is redefined, and \fIjpg\fR definition is deleted:
+This example configuration will serve the files from the local directory \fI/var/www\fR in the address \fIhttp://example\&.org:5280/pub/content/\fR\&. In this example a new content type \fIogg\fR is defined, \fIpng\fR is redefined, and \fIjpg\fR definition is deleted:
.sp
.if n \{\
.RS 4
.\}
.nf
listen:
- \&.\&.\&.
\-
port: 5280
module: ejabberd_http
request_handlers:
- \&.\&.\&.
- /pub/archive: mod_http_fileserver
- \&.\&.\&.
- \&.\&.\&.
+ /pub/content: mod_http_fileserver
modules:
- \&.\&.\&.
mod_http_fileserver:
docroot: /var/www
accesslog: /var/log/ejabberd/access\&.log
@@ -2831,7 +3686,6 @@ modules:
\&.ogg: audio/ogg
\&.png: image/png
default_content_type: text/html
- \&.\&.\&.
.fi
.if n \{\
.RE
@@ -2841,7 +3695,7 @@ modules:
.sp
This module allows for requesting permissions to upload a file via HTTP as described in XEP\-0363: HTTP File Upload\&. If the request is accepted, the client receives a URL for uploading the file and another URL from which that file can later be downloaded\&.
.sp
-In order to use this module, it must be enabled in \fIlisten\fR → \fIejabberd_http\fR → request_handlers\&.
+In order to use this module, it must be enabled in \fIlisten\fR → \fIejabberd_http\fR → \fIlisten\-options\&.md#request_handlers|request_handlers\fR\&.
.sp
.it 1 an-trap
.nr an-no-space-flag 1
@@ -2866,26 +3720,34 @@ This option specifies additional header fields to be included in all HTTP respon
.RS 4
This option defines the permission bits of the
\fIdocroot\fR
-directory and any directories created during file uploads\&. The bits are specified as an octal number (see the chmod(1) manual page) within double quotes\&. For example: "0755"\&. The default is undefined, which means no explicit permissions will be set\&.
+directory and any directories created during file uploads\&. The bits are specified as an octal number (see the
+\fIchmod(1)\fR
+manual page) within double quotes\&. For example:
+\fI"0755"\fR\&. The default is undefined, which means no explicit permissions will be set\&.
.RE
.PP
\fBdocroot\fR: \fIPath\fR
.RS 4
-Uploaded files are stored below the directory specified (as an absolute path) with this option\&. The keyword @HOME@ is replaced with the home directory of the user running ejabberd, and the keyword @HOST@ with the virtual host name\&. The default value is "@HOME@/upload"\&.
+Uploaded files are stored below the directory specified (as an absolute path) with this option\&. The keyword
+\fI@HOME@\fR
+is replaced with the home directory of the user running ejabberd, and the keyword
+\fI@HOST@\fR
+with the virtual host name\&. The default value is
+\fI"@HOME@/upload"\fR\&.
.RE
.PP
\fBexternal_secret\fR: \fIText\fR
.RS 4
This option makes it possible to offload all HTTP Upload processing to a separate HTTP server\&. Both ejabberd and the HTTP server should share this secret and behave exactly as described at
-Prosody\(cqs mod_http_upload_external
-in the
-\fIImplementation\fR
-section\&. There is no default value\&.
+Prosody\(cqs mod_http_upload_external: Implementation\&. There is no default value\&.
.RE
.PP
\fBfile_mode\fR: \fIPermission\fR
.RS 4
-This option defines the permission bits of uploaded files\&. The bits are specified as an octal number (see the chmod(1) manual page) within double quotes\&. For example: "0644"\&. The default is undefined, which means no explicit permissions will be set\&.
+This option defines the permission bits of uploaded files\&. The bits are specified as an octal number (see the
+\fIchmod(1)\fR
+manual page) within double quotes\&. For example:
+\fI"0644"\fR\&. The default is undefined, which means no explicit permissions will be set\&.
.RE
.PP
\fBget_url\fR: \fIURL\fR
@@ -2893,8 +3755,9 @@ This option defines the permission bits of uploaded files\&. The bits are specif
This option specifies the initial part of the GET URLs used for downloading the files\&. The default value is
\fIundefined\fR\&. When this option is
\fIundefined\fR, this option is set to the same value as
-\fIput_url\fR\&. The keyword @HOST@ is replaced with the virtual host name\&. NOTE: if GET requests are handled by
-\fImod_http_upload\fR, the
+\fIput_url\fR\&. The keyword
+\fI@HOST@\fR
+is replaced with the virtual host name\&. NOTE: if GET requests are handled by this module, the
\fIget_url\fR
must match the
\fIput_url\fR\&. Setting it to a different value only makes sense if an external web server or
@@ -2913,7 +3776,8 @@ instead\&.
.RS 4
This option defines the Jabber IDs of the service\&. If the
\fIhosts\fR
-option is not specified, the only Jabber ID will be the hostname of the virtual host with the prefix "upload\&."\&. The keyword
+option is not specified, the only Jabber ID will be the hostname of the virtual host with the prefix
+\fI"upload\&."\fR\&. The keyword
\fI@HOST@\fR
is replaced with the real virtual host name\&.
.RE
@@ -2936,12 +3800,18 @@ must be specified\&. The default value is
.PP
\fBname\fR: \fIName\fR
.RS 4
-A name of the service in the Service Discovery\&. This will only be displayed by special XMPP clients\&. The default value is "HTTP File Upload"\&.
+A name of the service in the Service Discovery\&. The default value is
+\fI"HTTP File Upload"\fR\&. Please note this will only be displayed by some XMPP clients\&.
.RE
.PP
\fBput_url\fR: \fIURL\fR
.RS 4
-This option specifies the initial part of the PUT URLs used for file uploads\&. The keyword @HOST@ is replaced with the virtual host name\&. NOTE: different virtual hosts cannot use the same PUT URL\&. The default value is "https://@HOST@:5443/upload"\&.
+This option specifies the initial part of the PUT URLs used for file uploads\&. The keyword
+\fI@HOST@\fR
+is replaced with the virtual host name\&. And
+\fI@HOST_URL_ENCODE@\fR
+is replaced with the host name encoded for URL, useful when your virtual hosts contain non\-latin characters\&. NOTE: different virtual hosts cannot use the same PUT URL\&. The default value is
+\fI"https://@HOST@:5443/upload"\fR\&.
.RE
.PP
\fBrm_on_unregister\fR: \fItrue | false\fR
@@ -2953,7 +3823,9 @@ This option specifies whether files uploaded by a user should be removed when th
\fBsecret_length\fR: \fILength\fR
.RS 4
This option defines the length of the random string included in the GET and PUT URLs generated by
-\fImod_http_upload\fR\&. The minimum length is 8 characters, but it is recommended to choose a larger value\&. The default value is
+\fImod_http_upload\fR\&. The minimum length is
+\fI8\fR
+characters, but it is recommended to choose a larger value\&. The default value is
\fI40\fR\&.
.RE
.PP
@@ -2974,30 +3846,22 @@ A custom vCard of the service that will be displayed by some XMPP clients in Ser
\fIvCard\fR
is a YAML map constructed from an XML representation of vCard\&. Since the representation has no attributes, the mapping is straightforward\&.
.sp
-For example, the following XML representation of vCard:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-
- Conferences
-
-
- Elm Street
-
-
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-will be translated to:
+\fBExample\fR:
.sp
.if n \{\
.RS 4
.\}
.nf
+# This XML representation of vCard:
+#
+# Conferences
+#
+#
+# Elm Street
+#
+#
+#
+# is translated to:
vcard:
fn: Conferences
adr:
@@ -3024,23 +3888,17 @@ vcard:
.\}
.nf
listen:
- \&.\&.\&.
\-
port: 5443
module: ejabberd_http
tls: true
request_handlers:
- \&.\&.\&.
/upload: mod_http_upload
- \&.\&.\&.
- \&.\&.\&.
modules:
- \&.\&.\&.
mod_http_upload:
docroot: /ejabberd/upload
put_url: "https://@HOST@:5443/upload"
- \&.\&.\&.
.fi
.if n \{\
.RE
@@ -3062,7 +3920,7 @@ This module depends on \fImod_http_upload\fR\&.
.PP
\fBaccess_hard_quota\fR: \fIAccessName\fR
.RS 4
-This option defines which access rule is used to specify the "hard quota" for the matching JIDs\&. That rule must yield a positive number for any JID that is supposed to have a quota limit\&. This is the number of megabytes a corresponding user may upload\&. When this threshold is exceeded, ejabberd deletes the oldest files uploaded by that user until their disk usage equals or falls below the specified soft quota (see
+This option defines which access rule is used to specify the "hard quota" for the matching JIDs\&. That rule must yield a positive number for any JID that is supposed to have a quota limit\&. This is the number of megabytes a corresponding user may upload\&. When this threshold is exceeded, ejabberd deletes the oldest files uploaded by that user until their disk usage equals or falls below the specified soft quota (see also option
\fIaccess_soft_quota\fR)\&. The default value is
\fIhard_upload_quota\fR\&.
.RE
@@ -3092,26 +3950,22 @@ directory, once per day\&. The default value is
\fBExamples:\fR
.RS 4
.sp
-Please note that it\(cqs not necessary to specify the \fIaccess_hard_quota\fR and \fIaccess_soft_quota\fR options in order to use the quota feature\&. You can stick to the default names and just specify access rules such as those in this example:
+Notice it\(cqs not necessary to specify the \fIaccess_hard_quota\fR and \fIaccess_soft_quota\fR options in order to use the quota feature\&. You can stick to the default names and just specify access rules such as those in this example:
.sp
.if n \{\
.RS 4
.\}
.nf
shaper_rules:
- \&.\&.\&.
soft_upload_quota:
1000: all # MiB
hard_upload_quota:
1100: all # MiB
- \&.\&.\&.
modules:
- \&.\&.\&.
mod_http_upload: {}
mod_http_upload_quota:
max_days: 100
- \&.\&.\&.
.fi
.if n \{\
.RE
@@ -3205,7 +4059,23 @@ This type of authentication was obsoleted in 2008 and you unlikely need this mod
The module has no options\&.
.SS "mod_mam"
.sp
-This module implements XEP\-0313: Message Archive Management\&. Compatible XMPP clients can use it to store their chat history on the server\&.
+This module implements XEP\-0313: Message Archive Management and XEP\-0441: Message Archive Management Preferences\&. Compatible XMPP clients can use it to store their chat history on the server\&.
+.if n \{\
+.sp
+.\}
+.RS 4
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBNote\fR
+.ps -1
+.br
+.sp
+Mnesia backend for mod_mam is not recommended: it\(cqs limited to 2GB and often gets corrupted when reaching this limit\&. SQL backend is recommended\&. Namely, for small servers SQLite is a preferred choice because it\(cqs very easy to configure\&.
+.sp .5v
+.RE
.sp
.it 1 an-trap
.nr an-no-space-flag 1
@@ -3300,9 +4170,113 @@ option, but applied to this module only\&.
.PP
\fBuser_mucsub_from_muc_archive\fR: \fItrue | false\fR
.RS 4
-When this option is disabled, for each individual subscriber a separa mucsub message is stored\&. With this option enabled, when a user fetches archive virtual mucsub, messages are generated from muc archives\&. The default value is
+When this option is disabled, for each individual subscriber a separate mucsub message is stored\&. With this option enabled, when a user fetches archive virtual mucsub, messages are generated from muc archives\&. The default value is
\fIfalse\fR\&.
.RE
+.sp
+\fBAPI Tags:\fR \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#mam|mam\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#purge|purge\fR
+.RE
+.SS "mod_matrix_gw 🟤"
+.sp
+\fINote\fR about this option: improved in 25\&.08\&.
+.sp
+Matrix gateway\&. Supports room versions 9, 10 and 11 since ejabberd 25\&.03; room versions 4 and higher since ejabberd 25\&.07; room version 12 (hydra rooms) since ejabberd 25\&.08\&. Erlang/OTP 25 or higher is required to use this module\&. This module is available since ejabberd 24\&.02\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBAvailable options:\fR
+.RS 4
+.PP
+\fBhost\fR: \fIHost\fR
+.RS 4
+This option defines the Jabber IDs of the service\&. If the
+\fIhost\fR
+option is not specified, the Jabber ID will be the hostname of the virtual host with the prefix
+\fI"matrix\&."\fR\&. The keyword
+\fI@HOST@\fR
+is replaced with the real virtual host name\&.
+.RE
+.PP
+\fBkey\fR: \fIstring()\fR
+.RS 4
+Value of the matrix signing key, in base64\&.
+.RE
+.PP
+\fBkey_name\fR: \fIstring()\fR
+.RS 4
+Name of the matrix signing key\&.
+.RE
+.PP
+\fBleave_timeout\fR: \fIinteger()\fR
+.RS 4
+Delay in seconds between a user leaving a MUC room and sending
+\fIleave\fR
+Matrix event\&.
+.RE
+.PP
+\fBmatrix_domain\fR: \fIDomain\fR
+.RS 4
+Specify a domain in the Matrix federation\&. The keyword
+\fI@HOST@\fR
+is replaced with the hostname\&. The default value is
+\fI@HOST@\fR\&.
+.RE
+.PP
+\fBmatrix_id_as_jid\fR: \fItrue | false\fR
+.RS 4
+If set to
+\fItrue\fR, all packets failing to be delivered via an XMPP server\-to\-server connection will then be routed to the Matrix gateway by translating a Jabber ID
+\fIuser@matrixdomain\&.tld\fR
+to a Matrix user identifier
+\fI@user:matrixdomain\&.tld\fR\&. When set to
+\fIfalse\fR, messages must be explicitly sent to the matrix gateway service Jabber ID to be routed to a remote Matrix server\&. In this case, to send a message to Matrix user
+\fI@user:matrixdomain\&.tld\fR, the client must send a message to the JID
+\fIuser%\fR\fImatrixdomain\&.tld@matrix\&.myxmppdomain\fR\fI\&.tld\fR, where
+\fImatrix\&.myxmppdomain\&.tld\fR
+is the JID of the gateway service as set by the
+\fIhost\fR
+option\&. The default is
+\fIfalse\fR\&.
+.RE
+.PP
+\fBnotary_servers\fR: \fI[Server, \&.\&.\&.]\fR
+.RS 4
+A list of notary servers\&.
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBExample:\fR
+.RS 4
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+listen:
+ \-
+ port: 8448
+ module: ejabberd_http
+ tls: true
+ request_handlers:
+ "/_matrix": mod_matrix_gw
+
+modules:
+ mod_matrix_gw:
+ key_name: "key1"
+ key: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+ matrix_id_as_jid: true
+.fi
+.if n \{\
+.RE
+.\}
.RE
.SS "mod_metrics"
.sp
@@ -3431,9 +4405,11 @@ An internet port number at which the backend is listening for incoming connectio
.RE
.SS "mod_mix"
.sp
-This module is an experimental implementation of XEP\-0369: Mediated Information eXchange (MIX)\&. MIX support was added in ejabberd 16\&.03 as an experimental feature, updated in 19\&.02, and is not yet ready to use in production\&. It\(cqs asserted that the MIX protocol is going to replace the MUC protocol in the future (see \fImod_muc\fR)\&.
+\fINote\fR about this option: added in 16\&.03 and improved in 19\&.02\&.
.sp
-To learn more about how to use that feature, you can refer to our tutorial: Getting started with XEP\-0369: Mediated Information eXchange (MIX) v0\&.1\&.
+This module is an experimental implementation of XEP\-0369: Mediated Information eXchange (MIX)\&. It\(cqs asserted that the MIX protocol is going to replace the MUC protocol in the future (see \fImod_muc\fR)\&.
+.sp
+To learn more about how to use that feature, you can refer to our tutorial: \fI\&.\&./\&.\&./tutorials/mix\-010\&.md|Getting started with MIX\fR
.sp
The module depends on \fImod_mam\fR\&.
.sp
@@ -3469,7 +4445,8 @@ instead\&.
.RS 4
This option defines the Jabber IDs of the service\&. If the
\fIhosts\fR
-option is not specified, the only Jabber ID will be the hostname of the virtual host with the prefix "mix\&."\&. The keyword
+option is not specified, the only Jabber ID will be the hostname of the virtual host with the prefix
+\fI"mix\&."\fR\&. The keyword
\fI@HOST@\fR
is replaced with the real virtual host name\&.
.RE
@@ -3545,7 +4522,7 @@ option, but applied to this module only\&.
.RE
.SS "mod_mqtt"
.sp
-This module adds support for the MQTT protocol version \fI3\&.1\&.1\fR and \fI5\&.0\fR\&. Remember to configure \fImod_mqtt\fR in \fImodules\fR and \fIlisten\fR sections\&.
+This module adds \fI\&.\&./guide/mqtt/index\&.md|support for the MQTT\fR protocol version \fI3\&.1\&.1\fR and \fI5\&.0\fR\&. Remember to configure \fImod_mqtt\fR in \fImodules\fR and \fIlisten\fR sections\&.
.sp
.it 1 an-trap
.nr an-no-space-flag 1
@@ -3647,12 +4624,97 @@ Same as top\-level
option, but applied to this module only\&.
.RE
.RE
+.SS "mod_mqtt_bridge"
+.sp
+This module adds ability to synchronize local MQTT topics with data on remote servers It can update topics on remote servers when local user updates local topic, or can subscribe for changes on remote server, and update local copy when remote data is updated\&. It is available since ejabberd 23\&.01\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBAvailable options:\fR
+.RS 4
+.PP
+\fBreplication_user\fR: \fIJID\fR
+.RS 4
+Identifier of a user that will be assigned as owner of local changes\&.
+.RE
+.PP
+\fBservers\fR: \fI{ServerUrl: {Key: Value}}\fR
+.RS 4
+Declaration of data to share for each ServerUrl\&. Server URLs can use schemas:
+\fImqtt\fR,
+\fImqtts\fR
+(mqtt with tls),
+\fImqtt5\fR,
+\fImqtt5s\fR
+(both to trigger v5 protocol),
+\fIws\fR,
+\fIwss\fR,
+\fIws5\fR,
+\fIwss5\fR\&. Keys must be:
+.PP
+\fBauthentication\fR: \fI{AuthKey: AuthValue}\fR
+.RS 4
+List of authentication information, where AuthKey can be:
+\fIusername\fR
+and
+\fIpassword\fR
+fields, or
+\fIcertfile\fR
+pointing to client certificate\&. Certificate authentication can be used only with mqtts, mqtt5s, wss, wss5\&.
+.RE
+.PP
+\fBpublish\fR: \fI{LocalTopic: RemoteTopic}\fR
+.RS 4
+Either publish or subscribe must be set, or both\&.
+.RE
+.PP
+\fBsubscribe\fR: \fI{RemoteTopic: LocalTopic}\fR
+.RS 4
+Either publish or subscribe must be set, or both\&.
+.RE
+.RE
+.RE
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBExample:\fR
+.RS 4
+.sp
+.if n \{\
+.RS 4
+.\}
+.nf
+modules:
+ mod_mqtt_bridge:
+ replication_user: "mqtt@xmpp\&.server\&.com"
+ servers:
+ "mqtt://server\&.com":
+ authentication:
+ certfile: "/etc/ejabberd/mqtt_server\&.pem"
+ publish:
+ "localA": "remoteA" # local changes to \*(AqlocalA\*(Aq will be replicated on remote server as \*(AqremoteA\*(Aq
+ "topicB": "topicB"
+ subscribe:
+ "remoteB": "localB" # changes to \*(AqremoteB\*(Aq on remote server will be stored as \*(AqlocalB\*(Aq on local server
+.fi
+.if n \{\
+.RE
+.\}
+.RE
.SS "mod_muc"
.sp
This module provides support for XEP\-0045: Multi\-User Chat\&. Users can discover existing rooms, join or create them\&. Occupants of a room can chat in public or have private chats\&.
.sp
The MUC service allows any Jabber ID to register a nickname, so nobody else can use that nickname in any room in the MUC service\&. To register a nickname, open the Service Discovery in your XMPP client and register in the MUC service\&.
.sp
+It is also possible to register a nickname in a room, so nobody else can use that nickname in that room\&. If a nick is registered in the MUC service, that nick cannot be registered in any room, and vice versa: a nick that is registered in a room cannot be registered at the MUC service\&.
+.sp
This module supports clustering and load balancing\&. One module can be started per cluster node\&. Rooms are distributed at creation time on all available MUC module instances\&. The multi\-user chat module is clustered but the rooms themselves are not clustered nor fault\-tolerant: if the node managing a set of rooms goes down, the rooms disappear and they will be recreated on an available node on first connection attempt\&.
.sp
.it 1 an-trap
@@ -3698,22 +4760,29 @@ room option\&. The default value is
.PP
\fBaccess_register\fR: \fIAccessName\fR
.RS 4
-This option specifies who is allowed to register nickname within the Multi\-User Chat service\&. The default is
+\fINote\fR
+about this option: improved in 23\&.10\&. This option specifies who is allowed to register nickname within the Multi\-User Chat service and rooms\&. The default is
\fIall\fR
-for backward compatibility, which means that any user is allowed to register any free nick\&.
+for backward compatibility, which means that any user is allowed to register any free nick in the MUC service and in the rooms\&.
+.RE
+.PP
+\fBcleanup_affiliations_on_start\fR: \fItrue | false\fR
+.RS 4
+\fINote\fR
+about this option: added in 22\&.05\&. Remove affiliations for non\-existing local users on startup\&. The default value is
+\fIfalse\fR\&.
.RE
.PP
\fBdb_type\fR: \fImnesia | sql\fR
.RS 4
-Define the type of persistent storage where the module will store room information\&. The default is the storage defined by the global option
-\fIdefault_db\fR, or
-\fImnesia\fR
-if omitted\&.
+Same as top\-level
+\fIdefault_db\fR
+option, but applied to this module only\&.
.RE
.PP
\fBdefault_room_options\fR: \fIOptions\fR
.RS 4
-This option allows to define the desired default room options\&. Note that the creator of a room can modify the options of his room at any time using an XMPP client with MUC capability\&. The
+Define the default room options\&. Note that the creator of a room can modify the options of his room at any time using an XMPP client with MUC capability\&. The
\fIOptions\fR
are:
.PP
@@ -3723,12 +4792,6 @@ Allow occupants to change the subject\&. The default value is
\fItrue\fR\&.
.RE
.PP
-\fBallow_private_messages\fR: \fItrue | false\fR
-.RS 4
-Occupants can send private messages to other occupants\&. The default value is
-\fItrue\fR\&.
-.RE
-.PP
\fBallow_private_messages_from_visitors\fR: \fIanyone | moderators | nobody\fR
.RS 4
Visitors can send private messages to other occupants\&. The default value is
@@ -3745,7 +4808,7 @@ Occupants can send IQ queries to other occupants\&. The default value is
\fBallow_subscription\fR: \fItrue | false\fR
.RS 4
Allow users to subscribe to room events as described in
-Multi\-User Chat Subscriptions\&. The default value is
+\fI\&.\&./\&.\&./developer/xmpp\-clients\-bots/extensions/muc\-sub\&.md|Multi\-User Chat Subscriptions\fR\&. The default value is
\fIfalse\fR\&.
.RE
.PP
@@ -3767,6 +4830,18 @@ Allow visitors to send status text in presence updates\&. If disallowed, the sta
\fItrue\fR\&.
.RE
.PP
+\fBallow_voice_requests\fR: \fItrue | false\fR
+.RS 4
+Allow visitors in a moderated room to request voice\&. The default value is
+\fItrue\fR\&.
+.RE
+.PP
+\fBallowpm\fR: \fIanyone | participants | moderators | none\fR
+.RS 4
+Who can send private messages\&. The default value is
+\fIanyone\fR\&.
+.RE
+.PP
\fBanonymous\fR: \fItrue | false\fR
.RS 4
The room is anonymous: occupants don\(cqt see the real JIDs of other occupants\&. Note that the room moderators can always see the real JIDs of the occupants\&. The default value is
@@ -3776,11 +4851,25 @@ The room is anonymous: occupants don\(cqt see the real JIDs of other occupants\&
\fBcaptcha_protected\fR: \fItrue | false\fR
.RS 4
When a user tries to join a room where they have no affiliation (not owner, admin or member), the room requires them to fill a CAPTCHA challenge (see section
-CAPTCHA
+\fIbasic\&.md#captcha|CAPTCHA\fR
in order to accept their join in the room\&. The default value is
\fIfalse\fR\&.
.RE
.PP
+\fBdescription\fR: \fIRoom Description\fR
+.RS 4
+Short description of the room\&. The default value is an empty string\&.
+.RE
+.PP
+\fBenable_hats\fR: \fItrue | false\fR
+.RS 4
+\fINote\fR
+about this option: improved in 25\&.03\&. Allow extended roles as defined in XEP\-0317 Hats\&. Check the
+\fI\&.\&./\&.\&./tutorials/muc\-hats\&.md|MUC Hats\fR
+tutorial\&. The default value is
+\fIfalse\fR\&.
+.RE
+.PP
\fBlang\fR: \fILanguage\fR
.RS 4
Preferred language for the discussions in the room\&. The language format should conform to RFC 5646\&. There is no value by default\&.
@@ -3843,7 +4932,7 @@ The room persists even if the last participant leaves\&. The default value is
\fIfalse\fR\&.
.RE
.PP
-\fBpresence_broadcast\fR: \fI[moderator | participant | visitor, \&.\&.\&.]\fR
+\fBpresence_broadcast\fR: \fI[Role]\fR
.RS 4
List of roles for which presence is broadcasted\&. The list can contain one or several of:
\fImoderator\fR,
@@ -3878,10 +4967,32 @@ The list of participants is public, without requiring to enter the room\&. The d
\fItrue\fR\&.
.RE
.PP
+\fBpubsub\fR: \fIPubSub Node\fR
+.RS 4
+XMPP URI of associated Publish/Subscribe node\&. The default value is an empty string\&.
+.RE
+.PP
\fBtitle\fR: \fIRoom Title\fR
.RS 4
A human\-readable title of the room\&. There is no default value
.RE
+.PP
+\fBvcard\fR: \fIvCard\fR
+.RS 4
+A custom vCard for the room\&. See the equivalent mod_muc option\&.The default value is an empty string\&.
+.RE
+.PP
+\fBvcard_xupdate\fR: \fIundefined | external | AvatarHash\fR
+.RS 4
+Set the hash of the avatar image\&. The default value is
+\fIundefined\fR\&.
+.RE
+.PP
+\fBvoice_request_min_interval\fR: \fINumber\fR
+.RS 4
+Minimum interval between voice requests, in seconds\&. The default value is
+\fI1800\fR\&.
+.RE
.RE
.PP
\fBhibernation_timeout\fR: \fIinfinity | Seconds\fR
@@ -3892,7 +5003,10 @@ Timeout before hibernating the room process, expressed in seconds\&. The default
.PP
\fBhistory_size\fR: \fISize\fR
.RS 4
-A small history of the current discussion is sent to users when they enter the room\&. With this option you can define the number of history messages to keep and send to users joining the room\&. The value is a non\-negative integer\&. Setting the value to 0 disables the history feature and, as a result, nothing is kept in memory\&. The default value is 20\&. This value affects all rooms on the service\&. NOTE: modern XMPP clients rely on Message Archives (XEP\-0313), so feel free to disable the history feature if you\(cqre only using modern clients and have
+A small history of the current discussion is sent to users when they enter the room\&. With this option you can define the number of history messages to keep and send to users joining the room\&. The value is a non\-negative integer\&. Setting the value to
+\fI0\fR
+disables the history feature and, as a result, nothing is kept in memory\&. The default value is
+\fI20\fR\&. This value affects all rooms on the service\&. NOTE: modern XMPP clients rely on Message Archives (XEP\-0313), so feel free to disable the history feature if you\(cqre only using modern clients and have
\fImod_mam\fR
module loaded\&.
.RE
@@ -3912,20 +5026,18 @@ option is not specified, the only Jabber ID will be the hostname of the virtual
\fI@HOST@\fR
is replaced with the real virtual host name\&.
.RE
-.sp
-\fINote\fR about the next option: added in 21\&.01:
.PP
\fBmax_captcha_whitelist\fR: \fINumber\fR
.RS 4
-This option defines the maximum number of characters that Captcha Whitelist can have when configuring the room\&. The default value is
+\fINote\fR
+about this option: added in 21\&.01\&. This option defines the maximum number of characters that Captcha Whitelist can have when configuring the room\&. The default value is
\fIinfinity\fR\&.
.RE
-.sp
-\fINote\fR about the next option: added in 21\&.01:
.PP
\fBmax_password\fR: \fINumber\fR
.RS 4
-This option defines the maximum number of characters that Password can have when configuring the room\&. The default value is
+\fINote\fR
+about this option: added in 21\&.01\&. This option defines the maximum number of characters that Password can have when configuring the room\&. The default value is
\fIinfinity\fR\&.
.RE
.PP
@@ -3974,18 +5086,22 @@ This option defines the number of service admins or room owners allowed to enter
.PP
\fBmax_users_presence\fR: \fINumber\fR
.RS 4
-This option defines after how many users in the room, it is considered overcrowded\&. When a MUC room is considered overcrowed, presence broadcasts are limited to reduce load, traffic and excessive presence "storm" received by participants\&. The default value is
+This option defines after how many users in the room, it is considered overcrowded\&. When a MUC room is considered overcrowded, presence broadcasts are limited to reduce load, traffic and excessive presence "storm" received by participants\&. The default value is
\fI1000\fR\&.
.RE
.PP
\fBmin_message_interval\fR: \fINumber\fR
.RS 4
-This option defines the minimum interval between two messages send by an occupant in seconds\&. This option is global and valid for all rooms\&. A decimal value can be used\&. When this option is not defined, message rate is not limited\&. This feature can be used to protect a MUC service from occupant abuses and limit number of messages that will be broadcasted by the service\&. A good value for this minimum message interval is 0\&.4 second\&. If an occupant tries to send messages faster, an error is send back explaining that the message has been discarded and describing the reason why the message is not acceptable\&.
+This option defines the minimum interval between two messages send by an occupant in seconds\&. This option is global and valid for all rooms\&. A decimal value can be used\&. When this option is not defined, message rate is not limited\&. This feature can be used to protect a MUC service from occupant abuses and limit number of messages that will be broadcasted by the service\&. A good value for this minimum message interval is
+\fI0\&.4\fR
+second\&. If an occupant tries to send messages faster, an error is send back explaining that the message has been discarded and describing the reason why the message is not acceptable\&.
.RE
.PP
\fBmin_presence_interval\fR: \fINumber\fR
.RS 4
-This option defines the minimum of time between presence changes coming from a given occupant in seconds\&. This option is global and valid for all rooms\&. A decimal value can be used\&. When this option is not defined, no restriction is applied\&. This option can be used to protect a MUC service for occupants abuses\&. If an occupant tries to change its presence more often than the specified interval, the presence is cached by ejabberd and only the last presence is broadcasted to all occupants in the room after expiration of the interval delay\&. Intermediate presence packets are silently discarded\&. A good value for this option is 4 seconds\&.
+This option defines the minimum of time between presence changes coming from a given occupant in seconds\&. This option is global and valid for all rooms\&. A decimal value can be used\&. When this option is not defined, no restriction is applied\&. This option can be used to protect a MUC service for occupants abuses\&. If an occupant tries to change its presence more often than the specified interval, the presence is cached by ejabberd and only the last presence is broadcasted to all occupants in the room after expiration of the interval delay\&. Intermediate presence packets are silently discarded\&. A good value for this option is
+\fI4\fR
+seconds\&.
.RE
.PP
\fBname\fR: \fIstring()\fR
@@ -4010,9 +5126,9 @@ option, but applied to this module only\&.
.PP
\fBram_db_type\fR: \fImnesia | sql\fR
.RS 4
-Define the type of volatile (in\-memory) storage where the module will store room information (\fImuc_online_room\fR
-and
-\fImuc_online_users\fR)\&.
+Same as top\-level
+\fIdefault_ram_db\fR
+option, but applied to this module only\&.
.RE
.PP
\fBregexp_room_id\fR: \fIstring()\fR
@@ -4044,30 +5160,22 @@ A custom vCard of the service that will be displayed by some XMPP clients in Ser
\fIvCard\fR
is a YAML map constructed from an XML representation of vCard\&. Since the representation has no attributes, the mapping is straightforward\&.
.sp
-For example, the following XML representation of vCard:
-.sp
-.if n \{\
-.RS 4
-.\}
-.nf
-
- Conferences
-
-
- Elm Street
-
-
-.fi
-.if n \{\
-.RE
-.\}
-.sp
-will be translated to:
+\fBExample\fR:
.sp
.if n \{\
.RS 4
.\}
.nf
+# This XML representation of vCard:
+#
+# Conferences
+#
+#
+# Elm Street
+#
+#
+#
+# is translated to:
vcard:
fn: Conferences
adr:
@@ -4086,7 +5194,25 @@ This module provides commands to administer local MUC services and their MUC roo
.sp
This module depends on \fImod_muc\fR\&.
.sp
-The module has no options\&.
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBAvailable options:\fR
+.RS 4
+.PP
+\fBsubscribe_room_many_max_users\fR: \fINumber\fR
+.RS 4
+\fINote\fR
+about this option: added in 22\&.05\&. How many users can be subscribed to a room at once using the
+\fIsubscribe_room_many\fR
+API\&. The default value is
+\fI50\fR\&.
+.RE
+.sp
+\fBAPI Tags:\fR \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#muc|muc\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#muc_room|muc_room\fR, \fI\&.\&./\&.\&./developer/ejabberd\-api/admin\-tags\&.md#muc_sub|muc_sub\fR
+.RE
.SS "mod_muc_log"
.sp
This module enables optional logging of Multi\-User Chat (MUC) public conversations to HTML\&. Once you enable this module, users can join a room using a MUC capable XMPP client, and if they have enough privileges, they can request the configuration form in which they can set the option to enable room logging\&.
@@ -4245,7 +5371,7 @@ to a remote file\&. By default a predefined CSS will be embedded into the HTML p
.PP
\fBdirname\fR: \fIroom_jid | room_name\fR
.RS 4
-Allows to configure the name of the room directory\&. If set to
+Configure the name of the room directory\&. If set to
\fIroom_jid\fR, the room directory name will be the full room JID\&. Otherwise, the room directory name will be only the room name, not including the MUC service name\&. The default value is
\fIroom_jid\fR\&.
.RE
@@ -4339,6 +5465,43 @@ or a conference JID is appended to the
otherwise\&. There is no default value\&.
.RE
.RE
+.SS "mod_muc_occupantid"
+.sp
+\fINote\fR about this option: added in 23\&.10\&.
+.sp
+This module implements XEP\-0421: Anonymous unique occupant identifiers for MUCs\&.
+.sp
+When the module is enabled, the feature is enabled in all semi\-anonymous rooms\&.
+.sp
+The module has no options\&.
+.SS "mod_muc_rtbl"
+.sp
+\fINote\fR about this option: added in 23\&.04\&.
+.sp
+This module implement Real\-time blocklists for MUC rooms\&.
+.sp
+It works by observing remote pubsub node conforming with specification described in https://xmppbl\&.org/\&.
+.sp
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.br
+.ps +1
+\fBAvailable options:\fR
+.RS 4
+.PP
+\fBrtbl_node\fR: \fIPubsubNodeName\fR
+.RS 4
+Name of pubsub node that should be used to track blocked users\&. The default value is
+\fImuc_bans_sha256\fR\&.
+.RE
+.PP
+\fBrtbl_server\fR: \fIDomain\fR
+.RS 4
+Domain of xmpp server that serves block list\&. The default value is
+\fIxmppbl\&.org\fR
+.RE
+.RE
.SS "mod_multicast"
.sp
This module implements a service for XEP\-0033: Extended Stanza Addressing\&.
@@ -4504,22 +5667,8 @@ modules:
.SS "mod_offline"
.sp
This module implements XEP\-0160: Best Practices for Handling Offline Messages and XEP\-0013: Flexible Offline Message Retrieval\&. This means that all messages sent to an offline user will be stored on the server until that user comes online again\&. Thus it is very similar to how email works\&. A user is considered offline if no session presence priority > 0 are currently open\&.
-.if n \{\
.sp
-.\}
-.RS 4
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.br
-.ps +1
-\fBNote\fR
-.ps -1
-.br
-.sp
-\fIejabberdctl\fR has a command to delete expired messages (see chapter Managing an ejabberd server in online documentation\&.
-.sp .5v
-.RE
+The \fIdelete_expired_messages\fR API allows to delete expired messages, and \fIdelete_old_messages\fR API deletes older ones\&.
.sp
.it 1 an-trap
.nr an-no-space-flag 1
@@ -4531,15 +5680,17 @@ This module implements XEP\-0160: Best Practices for Handling Offline Messages a
.PP
\fBaccess_max_user_messages\fR: \fIAccessName\fR
.RS 4
-This option defines which access rule will be enforced to limit the maximum number of offline messages that a user can have (quota)\&. When a user has too many offline messages, any new messages that they receive are discarded, and a error is returned to the sender\&. The default value is
+This option defines which access rule will be enforced to limit the maximum number of offline messages that a user can have (quota)\&. When a user has too many offline messages, any new messages that they receive are discarded, and a
+\fI\fR
+error is returned to the sender\&. The default value is
\fImax_user_offline_messages\fR\&.
.RE
.PP
\fBbounce_groupchat\fR: \fItrue | false\fR
.RS 4
-This option is use the disable an optimisation that avoids bouncing error messages when groupchat messages could not be stored as offline\&. It will reduce chat room load, without any drawback in standard use cases\&. You may change default value only if you have a custom module which uses offline hook after
+This option is use the disable an optimization that avoids bouncing error messages when groupchat messages could not be stored as offline\&. It will reduce chat room load, without any drawback in standard use cases\&. You may change default value only if you have a custom module which uses offline hook after
\fImod_offline\fR\&. This option can be useful for both standard MUC and MucSub, but the bounce is much more likely to happen in the context of MucSub, so it is even more important to have it on large MucSub services\&. The default value is
-\fIfalse\fR, meaning the optimisation is enabled\&.
+\fIfalse\fR, meaning the optimization is enabled\&.
.RE
.PP
\fBcache_life_time\fR: \fItimeout()\fR
@@ -4565,8 +5716,12 @@ option, but applied to this module only\&.
.PP
\fBstore_empty_body\fR: \fItrue | false | unless_chat_state\fR
.RS 4
-Whether or not to store messages that lack a element\&. The default value is
-\fIunless_chat_state\fR, which tells ejabberd to store messages even if they lack the element, unless they only contain a chat state notification (as defined in
+Whether or not to store messages that lack a
+\fI\fR
+element\&. The default value is
+\fIunless_chat_state\fR, which tells ejabberd to store messages even if they lack the
+\fI