aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md105
-rw-r--r--README.md2
-rw-r--r--mix.exs3
-rw-r--r--mix.lock6
-rw-r--r--src/ejabberd.erl2
-rw-r--r--src/ejabberd_auth_ldap.erl1
-rw-r--r--src/ejabberd_ctl.erl18
-rw-r--r--src/ejabberd_logger.erl7
-rw-r--r--src/ejabberd_piefxis.erl7
-rw-r--r--src/ejabberd_s2s.erl6
-rw-r--r--src/ejabberd_sql.erl5
-rw-r--r--src/ejabberd_web_admin.erl37
-rw-r--r--src/mod_admin_extra.erl3
-rw-r--r--src/mod_http_fileserver.erl7
-rw-r--r--src/mod_mqtt_session.erl2
-rw-r--r--src/mod_muc_admin.erl10
-rw-r--r--src/mod_pubsub.erl5
-rw-r--r--src/mod_roster_mnesia.erl1
-rw-r--r--src/mod_shared_roster.erl6
19 files changed, 165 insertions, 68 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2f804a359..758bddc0c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,108 @@
+# Version 22.05
+
+Core
+- C2S: Don't expect that socket will be available in `c2s_terminated` hook
+- Event handling process hook tracing
+- Guard against `erlang:system_info(logical_processors)` not always returning a number
+- `domain_balancing`: Allow for specifying `type` only, without specifying `component_number`
+
+MQTT
+- Add TLS certificate authentication for MQTT connections
+- Fix login when generating client id, keep connection record (#3593)
+- Pass property name as expected in mqtt_codec (fixes login using MQTT 5)
+- Support MQTT subscriptions spread over the cluster (#3750)
+
+MUC
+- Attach meta field with real jid to mucsub subscription events
+- Handle user removal
+- Stop empty MUC rooms 30 seconds after creation
+- `default_room_options`: Update options configurable
+- `subscribe_room_many_max_users`: New option in `mod_muc_admin`
+
+mod_conversejs
+- Improved options to support `@HOST@` and `auto` values
+- Set `auth` and `register` options based on ejabberd configuration
+- `conversejs_options`: New option
+- `conversejs_resources`: New option
+
+PubSub
+- `mod_pubsub`: Allow for limiting `item_expire` value
+- `mod_pubsub`: Unsubscribe JID on whitelist removal
+- `node_pep`: Add config-node and multi-items features (#3714)
+
+SQL
+- Improve compatibility with various db engine versions
+- Sync old-to-new schema script with reality (#3790)
+- Slight improvement in MSSQL testing support, but not yet complete
+
+Other Modules
+- `auth_jwt`: Checking if an user is active in SM for a JWT authenticated user (#3795)
+- `mod_configure`: Implement Get List of Registered/Online Users from XEP-0133
+- `mod_host_meta`: New module to serve host-meta files, see XEP-0156
+- `mod_mam`: Store all mucsub notifications not only message notifications
+- `mod_ping`: Delete ping timer if resource is gone after the ping has been sent
+- `mod_ping`: Don't send ping if resource is gone
+- `mod_push`: Fix notifications for pending sessions (XEP-0198)
+- `mod_push`: Keep push session ID on session resume
+- `mod_shared_roster`: Adjust special group cache size
+- `mod_shared_roster`: Normalize JID on unset_presence (#3752)
+- `mod_stun_disco`: Fix parsing of IPv6 listeners
+
+Dependencies
+- autoconf: Supported from 2.59 to the new 2.71
+- fast_tls: Update to 1.1.14 to support OpenSSL 3
+- jiffy: Update to 1.1.1 to support Erlang/OTP 25.0-rc1
+- luerl: Update to 1.0.0, now available in hex.pm
+- lager: This dependency is used only when Erlang is older than 22
+- rebar2: Updated binary to work from Erlang/OTP 22 to 25
+- rebar3: Updated binary to work from Erlang/OTP 22 to 25
+- `make update`: Fix when used with rebar 3.18
+
+Compile
+- `mix release`: Copy `include/` files for ejabberd, deps and otp, in `mix.exs`
+- `rebar3 release`: Fix ERTS path in `ejabberdctl`
+- `configure.ac`: Set default ejabberd version number when not using git
+- `mix.exs`: Move some dependencies as optional
+- `mix.exs`: No need to use Distillery, Elixir has built-in support for OTP releases (#3788)
+- `tools/make-binaries`: New script for building Linux binaries
+- `tools/make-installers`: New script for building command line installers
+
+Start
+- New `make relive` similar to `ejabberdctl live` without installing
+- `ejabberdctl`: Fix some warnings detected by ShellCheck
+- `ejabberdctl`: Mention in the help: `etop`, `ping` and `started`/`stopped`
+- `make rel`: Switch to paths: `conf/`, `database/`, `logs/`
+- `mix.exs`: Add `-boot` and `-boot_var` in `ejabberdctl` instead of adding `vm.args`
+- `tools/captcha.sh`: Fix some warnings detected by ShellCheck
+
+Commands
+- Accept more types of ejabberdctl commands arguments as JSON-encoded
+- `delete_old_mam_messages_batch`: New command with rate limit
+- `delete_old_messages_batch`: New command with rate limit
+- `get_room_occupants_number`: Don't request the whole MUC room state (#3684, #1964)
+- `get_vcard`: Add support for MUC room vCard
+- `oauth_revoke_token`: Add support to work with all backends
+- `room_unused_*`: Optimize commands in SQL by reusing `created_at`
+- `rooms_unused_...`: Let `get_all_rooms` handle `global` argument (#3726)
+- `stop|restart`: Terminate ejabberd_sm before everything else to ensure sessions closing (#3641)
+- `subscribe_room_many`: New command
+
+Translations
+- Updated Catalan
+- Updated French
+- Updated German
+- Updated Portuguese
+- Updated Portuguese (Brazil)
+- Updated Spanish
+
+Workflows
+- CI: Publish CT logs and Cover on failure to an external GH Pages repo
+- CI: Test shell scripts using ShellCheck (#3738)
+- Container: New workflow to build and publish containers
+- Installers: Add job to create draft release
+- Installers: New workflow to build binary packages
+- Runtime: New workflow to test compilation, rel, starting and ejabberdctl
+
# Version 21.12
Commands
diff --git a/README.md b/README.md
index e40f7701b..7d526ee55 100644
--- a/README.md
+++ b/README.md
@@ -38,7 +38,6 @@ Installation
There are several ways to install ejabberd:
- Source code: compile yourself, see [COMPILE](COMPILE.md)
-- Installers from [ProcessOne Downloads][p1dl] (run/deb/rpm for x64)
- Installers from [ejabberd GitHub Releases][releases] (run/deb/rpm for x64 and arm64)
- Container image from [ejabberd Docker Hub][hubecs], see [ecs README][docker-ecs-readme] (for x64)
- Container image from [ejabberd Github Packages][packages], see [CONTAINER](CONTAINER.md) (for x64 and arm64)
@@ -117,7 +116,6 @@ and [ejabberd translations](https://github.com/processone/ejabberd-po/) under MI
[muc]: xmpp:ejabberd@conference.process-one.net
[osp]: https://docs.ejabberd.im/admin/installation/#operating-system-packages
[p1contact]: https://www.process-one.net/en/company/contact/
-[p1dl]: https://www.process-one.net/en/ejabberd/downloads/
[p1home]: https://www.process-one.net/en/ejabberd/
[packages]: https://github.com/processone/ejabberd/pkgs/container/ejabberd
[releases]: https://github.com/processone/ejabberd/releases
diff --git a/mix.exs b/mix.exs
index d73489797..b3348a6ec 100644
--- a/mix.exs
+++ b/mix.exs
@@ -101,6 +101,7 @@ defmodule Ejabberd.MixProject do
[{:base64url, "~> 1.0"},
{:cache_tab, "~> 1.0"},
{:eimp, "~> 1.0"},
+ {:ex_doc, ">= 0.0.0", only: :dev},
{:fast_tls, "~> 1.1"},
{:fast_xml, "~> 1.1"},
{:fast_yaml, "~> 1.0"},
@@ -163,7 +164,7 @@ defmodule Ejabberd.MixProject do
"COPYING", "README.md",
"mix.exs", "rebar.config", "rebar.config.script", "vars.config"],
maintainers: ["ProcessOne"],
- licenses: ["GPLv2"],
+ licenses: ["GPL-2.0-or-later"],
links: %{"Site" => "https://www.ejabberd.im",
"Documentation" => "http://docs.ejabberd.im",
"Source" => "https://github.com/processone/ejabberd",
diff --git a/mix.lock b/mix.lock
index 54d08fb1d..2b9e73b64 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,10 +1,12 @@
%{
"base64url": {:hex, :base64url, "1.0.1", "f8c7f2da04ca9a5d0f5f50258f055e1d699f0e8bf4cfdb30b750865368403cf6", [:rebar3], [], "hexpm", "f9b3add4731a02a9b0410398b475b33e7566a695365237a6bdee1bb447719f5c"},
"cache_tab": {:hex, :cache_tab, "1.0.30", "6d35eecfb65fbe5fc85988503a27338d32de01243f3fc8ea3ee7161af08725a4", [:rebar3], [{:p1_utils, "1.0.25", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "6d8a5e00d8f84c42627706a6dbedb02e34d58495f3ed61935c8475ca0531cda0"},
+ "earmark_parser": {:hex, :earmark_parser, "1.4.25", "2024618731c55ebfcc5439d756852ec4e85978a39d0d58593763924d9a15916f", [:mix], [], "hexpm", "56749c5e1c59447f7b7a23ddb235e4b3defe276afc220a6227237f3efe83f51e"},
"eimp": {:hex, :eimp, "1.0.22", "fa9b376ef0b50e8455db15c7c11dea4522c6902e04412288aab436d26335f6eb", [:rebar3], [{:p1_utils, "1.0.25", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "b3b9ffb1d9a5f4a2ba88ac418a819164932d9a9d3a2fc3d32ca338ce855c4392"},
"epam": {:hex, :epam, "1.0.12", "2a5625d4133bca4b3943791a3f723ba764455a461ae9b6ba5debb262efcf4b40", [:rebar3], [], "hexpm", "54c166c4459cef72f2990a3d89a8f0be27180fe0ab0f24b28ddcc3b815f49f7f"},
"eredis": {:hex, :eredis, "1.2.0", "0b8e9cfc2c00fa1374cd107ea63b49be08d933df2cf175e6a89b73dd9c380de4", [:rebar3], [], "hexpm", "d9b5abef2c2c8aba8f32aa018203e0b3dc8b1157773b254ab1d4c2002317f1e1"},
"esip": {:hex, :esip, "1.0.47", "fdd483ca7e9e46a6d5a62937cbacb147adbe0bdfca5ebc59774cc0a1afa381be", [:rebar3], [{:fast_tls, "1.1.15", [hex: :fast_tls, repo: "hexpm", optional: false]}, {:p1_utils, "1.0.25", [hex: :p1_utils, repo: "hexpm", optional: false]}, {:stun, "1.2.2", [hex: :stun, repo: "hexpm", optional: false]}], "hexpm", "99e703c49e8d325b24cb147c5087151c196406e8572e3a33db95099991fe8f3e"},
+ "ex_doc": {:hex, :ex_doc, "0.28.4", "001a0ea6beac2f810f1abc3dbf4b123e9593eaa5f00dd13ded024eae7c523298", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "bf85d003dd34911d89c8ddb8bda1a958af3471a274a4c2150a9c01c78ac3f8ed"},
"ezlib": {:hex, :ezlib, "1.0.12", "ffe906ba10d03aaee7977e1e0e81d9ffc3bb8b47fb9cd8e2e453507a2e56221f", [:rebar3], [{:p1_utils, "1.0.25", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "30e94355fb42260aab6e12582cb0c56bf233515e655c8aeaf48760e7561e4ebb"},
"fast_tls": {:hex, :fast_tls, "1.1.15", "398e7ba1076db139307ebea839428e2836ab682e4dac61d95b4705a26aff06b7", [:rebar3], [{:p1_utils, "1.0.25", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "ef516aa226de9a4605704c18499284cd4fc115a73bd72490341972ce0c2b4d30"},
"fast_xml": {:hex, :fast_xml, "1.1.49", "67d9bfcadd04efd930e0ee1412b5ea09d3e791f1fdbd4d3e9a8c8f29f8bfed8c", [:rebar3], [{:p1_utils, "1.0.25", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "01da064d2f740818956961036637fee2475c17bf8aab9442217f90dc77883593"},
@@ -13,7 +15,11 @@
"jiffy": {:hex, :jiffy, "1.1.1", "aca10f47aa91697bf24ab9582c74e00e8e95474c7ef9f76d4f1a338d0f5de21b", [:rebar3], [], "hexpm", "62e1f0581c3c19c33a725c781dfa88410d8bff1bbafc3885a2552286b4785c4c"},
"jose": {:hex, :jose, "1.11.1", "59da64010c69aad6cde2f5b9248b896b84472e99bd18f246085b7b9fe435dcdb", [:mix, :rebar3], [], "hexpm", "078f6c9fb3cd2f4cfafc972c814261a7d1e8d2b3685c0a76eb87e158efff1ac5"},
"luerl": {:hex, :luerl, "1.0.0", "1b68c30649323590d5339b967b419260500ffe520cd3abc1987482a82d3b5a6c", [:rebar3], [], "hexpm", "c17bc45cb4b0845ec975387f9a5d8c81ab60456698527a29c96f78992af86bd1"},
+ "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
+ "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
+ "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"mqtree": {:hex, :mqtree, "1.0.15", "bc54d8b88698fdaebc1e27a9ac43688b927e3dbc05bd5cee4057e69a89a8cf17", [:rebar3], [{:p1_utils, "1.0.25", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "294ac43c9b3d372e24eeea56c259e19c655522dcff64a55c401a639663b9d829"},
+ "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
"p1_acme": {:hex, :p1_acme, "1.0.19", "5c4cb2bf627c526e242a0106eef0015b98b440b1aa03fd29e44c62c6b26cd545", [:rebar3], [{:base64url, "1.0.1", [hex: :base64url, repo: "hexpm", optional: false]}, {:idna, "6.0.0", [hex: :idna, repo: "hexpm", optional: false]}, {:jiffy, "1.1.1", [hex: :jiffy, repo: "hexpm", optional: false]}, {:jose, "1.11.1", [hex: :jose, repo: "hexpm", optional: false]}, {:yconf, "1.0.13", [hex: :yconf, repo: "hexpm", optional: false]}], "hexpm", "904023023ca1d5785d1f3ba5670676d30abafd52445e4b60236d2571cc7b550c"},
"p1_mysql": {:hex, :p1_mysql, "1.0.19", "22f1be58397780a7d580a954e7af66cde32a29dee1a24ab2aa196272fc654a4a", [:rebar3], [], "hexpm", "88f6cdb510e8959c14b6ae84ccda04967e3de239228f859d8341da67949622b1"},
"p1_oauth2": {:hex, :p1_oauth2, "0.6.11", "96b4e85c08355720523c2f892011a81a07994d15c179ce4dd82d704fecad15b2", [:rebar3], [], "hexpm", "9c3c6ae59382b9525473bb02a32949889808f33f95f6db10594fd92acd1f63db"},
diff --git a/src/ejabberd.erl b/src/ejabberd.erl
index d39af1400..048eb7d98 100644
--- a/src/ejabberd.erl
+++ b/src/ejabberd.erl
@@ -52,7 +52,7 @@ halt() ->
ejabberd_logger:flush(),
erlang:halt(1, [{flush, true}]).
-%% @spec () -> false | string()
+-spec get_pid_file() -> false | string().
get_pid_file() ->
case os:getenv("EJABBERD_PID_PATH") of
false ->
diff --git a/src/ejabberd_auth_ldap.erl b/src/ejabberd_auth_ldap.erl
index 1c3143241..9195d2498 100644
--- a/src/ejabberd_auth_ldap.erl
+++ b/src/ejabberd_auth_ldap.erl
@@ -151,7 +151,6 @@ get_users(Server, []) ->
count_users(Server, Opts) ->
length(get_users(Server, Opts)).
-%% @spec (User, Server) -> true | false | {error, Error}
user_exists(User, Server) ->
case catch user_exists_ldap(User, Server) of
{'EXIT', _Error} -> {nocache, {error, db_failure}};
diff --git a/src/ejabberd_ctl.erl b/src/ejabberd_ctl.erl
index 057cff66c..e715aac00 100644
--- a/src/ejabberd_ctl.erl
+++ b/src/ejabberd_ctl.erl
@@ -218,11 +218,11 @@ process(Args, Version) ->
end,
Code.
-%% @spec (Args::[string()], AccessCommands) -> {String::string(), Code::integer()}
+-spec process2(Args::[string()], AccessCommands::any()) ->
+ {String::string(), Code::integer()}.
process2(Args, AccessCommands) ->
process2(Args, AccessCommands, ?DEFAULT_VERSION).
-%% @spec (Args::[string()], AccessCommands, Version) -> {String::string(), Code::integer()}
process2(["--auth", User, Server, Pass | Args], AccessCommands, Version) ->
process2(Args, AccessCommands, {list_to_binary(User), list_to_binary(Server),
list_to_binary(Pass), true}, Version);
@@ -271,7 +271,6 @@ determine_string_type(String, Version) ->
%% Command calling
%%-----------------------------
-%% @spec (Args::[string()], Auth, AccessCommands, Version) -> string() | integer() | {string(), integer()}
try_run_ctp(Args, Auth, AccessCommands, Version) ->
try ejabberd_hooks:run_fold(ejabberd_ctl_process, false, [Args]) of
false when Args /= [] ->
@@ -292,7 +291,6 @@ try_run_ctp(Args, Auth, AccessCommands, Version) ->
{io_lib:format("Error in ejabberd ctl process: '~p' ~p", [Error, Why]), ?STATUS_USAGE}
end.
-%% @spec (Args::[string()], Auth, AccessCommands, Version) -> string() | integer() | {string(), integer()}
try_call_command(Args, Auth, AccessCommands, Version) ->
try call_command(Args, Auth, AccessCommands, Version) of
{Reason, wrong_command_arguments} ->
@@ -316,7 +314,11 @@ try_call_command(Args, Auth, AccessCommands, Version) ->
?STATUS_ERROR}
end.
-%% @spec (Args::[string()], Auth, AccessCommands, Version) -> string() | integer() | {string(), integer()} | {error, ErrorType}
+-spec call_command(Args::[string()],
+ Auth::noauth | {binary(), binary(), binary(), true},
+ AccessCommands::[any()],
+ Version::integer()) ->
+ string() | integer() | {string(), integer()} | {error, ErrorType::any()}.
call_command([CmdString | Args], Auth, _AccessCommands, Version) ->
CmdStringU = ejabberd_regexp:greplace(
list_to_binary(CmdString), <<"-">>, <<"_">>),
@@ -768,7 +770,8 @@ print_usage_help(MaxC, ShCode) ->
%% Print usage command
%%-----------------------------
-%% @spec (CmdSubString::string(), MaxC::integer(), ShCode::boolean(), Version) -> ok
+-spec print_usage_commands2(CmdSubString::string(), MaxC::integer(),
+ ShCode::boolean(), Version::integer()) -> ok.
print_usage_commands2(CmdSubString, MaxC, ShCode, Version) ->
%% Get which command names match this substring
AllCommandsNames = [atom_to_list(Name) || {Name, _, _} <- ejabberd_commands:list_commands(Version)],
@@ -814,7 +817,8 @@ filter_commands_regexp(All, Glob) ->
end,
All).
-%% @spec (Cmd::string(), MaxC::integer(), ShCode::boolean(), Version) -> ok
+-spec print_usage_command(Cmd::string(), MaxC::integer(),
+ ShCode::boolean(), Version::integer()) -> ok.
print_usage_command(Cmd, MaxC, ShCode, Version) ->
Name = list_to_atom(Cmd),
C = ejabberd_commands:get_command_definition(Name, Version),
diff --git a/src/ejabberd_logger.erl b/src/ejabberd_logger.erl
index 217b232fa..e4fe34e0e 100644
--- a/src/ejabberd_logger.erl
+++ b/src/ejabberd_logger.erl
@@ -113,7 +113,6 @@ get_string_env(Name, Default) ->
Default
end.
--spec start() -> ok.
start() ->
start(info).
@@ -181,17 +180,14 @@ do_start(Level) ->
lager:set_loghwm(Handler, LogRateLimit)
end, gen_event:which_handlers(lager_event)).
--spec restart() -> ok.
restart() ->
Level = ejabberd_option:loglevel(),
application:stop(lager),
start(Level).
--spec reopen_log() -> ok.
reopen_log() ->
ok.
--spec rotate_log() -> ok.
rotate_log() ->
catch lager_crash_log ! rotate,
lists:foreach(
@@ -201,7 +197,6 @@ rotate_log() ->
ok
end, gen_event:which_handlers(lager_event)).
--spec get() -> loglevel().
get() ->
Handlers = get_lager_handlers(),
lists:foldl(fun(lager_console_backend, _Acc) ->
@@ -213,7 +208,6 @@ get() ->
end,
none, Handlers).
--spec set(0..5 | loglevel()) -> ok.
set(N) when is_integer(N), N>=0, N=<5 ->
set(convert_loglevel(N));
set(Level) when ?is_loglevel(Level) ->
@@ -255,7 +249,6 @@ get_lager_version() ->
false -> "0.0.0"
end.
--spec flush() -> ok.
flush() ->
application:stop(lager),
application:stop(sasl).
diff --git a/src/ejabberd_piefxis.erl b/src/ejabberd_piefxis.erl
index add52770d..8f45efa99 100644
--- a/src/ejabberd_piefxis.erl
+++ b/src/ejabberd_piefxis.erl
@@ -642,33 +642,26 @@ make_host_filename(FnT, Host) ->
make_host_basefilename(Dir, FnT) ->
filename:join([Dir, FnT]).
-%% @spec () -> string()
make_piefxis_xml_head() ->
"<?xml version='1.0' encoding='UTF-8'?>".
-%% @spec () -> string()
make_piefxis_xml_tail() ->
"".
-%% @spec () -> string()
make_piefxis_server_head() ->
io_lib:format("<server-data xmlns='~ts' xmlns:xi='~ts'>",
[?NS_PIE, ?NS_XI]).
-%% @spec () -> string()
make_piefxis_server_tail() ->
"</server-data>".
-%% @spec (Host::string()) -> string()
make_piefxis_host_head(Host) ->
io_lib:format("<host xmlns='~ts' xmlns:xi='~ts' jid='~ts'>",
[?NS_PIE, ?NS_XI, Host]).
-%% @spec () -> string()
make_piefxis_host_tail() ->
"</host>".
-%% @spec (Fn::string()) -> string()
make_xinclude(Fn) ->
Base = filename:basename(Fn),
io_lib:format("<xi:include href='~ts'/>", [Base]).
diff --git a/src/ejabberd_s2s.erl b/src/ejabberd_s2s.erl
index 9b40ad717..b2b078098 100644
--- a/src/ejabberd_s2s.erl
+++ b/src/ejabberd_s2s.erl
@@ -589,10 +589,8 @@ allow_host1(MyHost, S2SHost) ->
end
end.
-%% Get information about S2S connections of the specified type.
-%% @spec (Type) -> [Info]
-%% where Type = in | out
-%% Info = [{InfoName::atom(), InfoValue::any()}]
+%% @doc Get information about S2S connections of the specified type.
+-spec get_info_s2s_connections(Type::in | out) -> [[{InfoName::atom(), InfoValue::any()}]].
get_info_s2s_connections(Type) ->
ChildType = case Type of
in -> ejabberd_s2s_in_sup;
diff --git a/src/ejabberd_sql.erl b/src/ejabberd_sql.erl
index d68d1a8e1..d0f7c658f 100644
--- a/src/ejabberd_sql.erl
+++ b/src/ejabberd_sql.erl
@@ -488,8 +488,9 @@ run_sql_cmd(Command, From, State, Timestamp) ->
abort_on_driver_error(outer_op(Command), From, Timestamp)
end.
-%% Only called by handle_call, only handles top level operations.
-%% @spec outer_op(Op) -> {error, Reason} | {aborted, Reason} | {atomic, Result}
+%% @doc Only called by handle_call, only handles top level operations.
+-spec outer_op(Op::{atom(), binary()}) ->
+ {error, Reason::binary()} | {aborted, Reason::binary()} | {atomic, Result::any()}.
outer_op({sql_query, Query}) ->
sql_query_internal(Query);
outer_op({sql_transaction, F}) ->
diff --git a/src/ejabberd_web_admin.erl b/src/ejabberd_web_admin.erl
index 7691dd794..46598e1ef 100644
--- a/src/ejabberd_web_admin.erl
+++ b/src/ejabberd_web_admin.erl
@@ -52,8 +52,8 @@
%%%==================================
%%%% get_acl_access
-%% @spec (Path::[string()], Method) -> {HostOfRule, [AccessRule]}
-%% where Method = 'GET' | 'POST'
+-spec get_acl_rule(Path::[binary()], 'GET' | 'POST') ->
+ {HostOfRule::binary(), [AccessRule::atom()]}.
%% All accounts can access those URLs
get_acl_rule([], _) -> {<<"localhost">>, [all]};
@@ -275,10 +275,13 @@ get_auth_account2(HostOfRule, AccessRule, User, Server,
make_xhtml(Els, Host, Lang, JID, Level) ->
make_xhtml(Els, Host, cluster, Lang, JID, Level).
-%% @spec (Els, Host, Node, Lang, JID, Level::integer()) -> {200, [html], xmlelement()}
-%% where Host = global | string()
-%% Node = cluster | atom()
-%% JID = jid()
+-spec make_xhtml([xmlel()],
+ Host::global | binary(),
+ Node::cluster | atom(),
+ Lang::binary(),
+ jid(),
+ Level::integer()) ->
+ {200, [html], xmlel()}.
make_xhtml(Els, Host, Node, Lang, JID, Level) ->
Base = get_base_path_sum(0, 0, Level),
MenuItems = make_navigation(Host, Node, Lang, JID, Level),
@@ -1877,18 +1880,15 @@ get_table_content(Node, Table, _Type, PageNumber, PageSize) ->
%%%==================================
%%%% navigation menu
-%% @spec (Host, Node, Lang, JID::jid(), Level::integer()) -> [LI]
make_navigation(Host, Node, Lang, JID, Level) ->
Menu = make_navigation_menu(Host, Node, Lang, JID, Level),
make_menu_items(Lang, Menu).
-%% @spec (Host, Node, Lang, JID::jid(), Level::integer()) -> Menu
-%% where Host = global | string()
-%% Node = cluster | string()
-%% Lang = string()
-%% Menu = {URL, Title} | {URL, Title, [Menu]}
-%% URL = string()
-%% Title = string()
+-spec make_navigation_menu(Host::global | binary(),
+ Node::cluster | atom(),
+ Lang::binary(), JID::jid(), Level::integer()) ->
+ Menu::{URL::binary(), Title::binary()}
+ | {URL::binary(), Title::binary(), [Menu::any()]}.
make_navigation_menu(Host, Node, Lang, JID, Level) ->
HostNodeMenu = make_host_node_menu(Host, Node, Lang,
JID, Level),
@@ -1897,7 +1897,6 @@ make_navigation_menu(Host, Node, Lang, JID, Level) ->
NodeMenu = make_node_menu(Host, Node, Lang, Level),
make_server_menu(HostMenu, NodeMenu, Lang, JID, Level).
-%% @spec (Host, Node, Base, Lang) -> [LI]
make_menu_items(global, cluster, Base, Lang) ->
HookItems = get_menu_items_hook(server, Lang),
make_menu_items(Lang, {Base, <<"">>, HookItems});
@@ -1978,9 +1977,11 @@ get_menu_items_hook({node, Node}, Lang) ->
get_menu_items_hook(server, Lang) ->
ejabberd_hooks:run_fold(webadmin_menu_main, [], [Lang]).
-%% @spec (Lang::string(), Menu) -> [LI]
-%% where Menu = {MURI::string(), MName::string(), Items::[Item]}
-%% Item = {IURI::string(), IName::string()} | {IURI::string(), IName::string(), Menu}
+-spec make_menu_items(Lang::binary(),
+ {MURI::binary(), MName::binary(),
+ Items::[{IURI::binary(), IName::binary()}
+ | {IURI::binary(), IName::binary(), Menu::any()}]}) ->
+ [xmlel()].
make_menu_items(Lang, Menu) ->
lists:reverse(make_menu_items2(Lang, 1, Menu)).
diff --git a/src/mod_admin_extra.erl b/src/mod_admin_extra.erl
index cc1996bbd..19aa983f5 100644
--- a/src/mod_admin_extra.erl
+++ b/src/mod_admin_extra.erl
@@ -1538,7 +1538,8 @@ srg_user_del(User, Host, Group, GroupHost) ->
%%%
%% @doc Send a message to an XMPP account.
-%% @spec (Type::binary(), From::binary(), To::binary(), Subject::binary(), Body::binary()) -> ok
+-spec send_message(Type::binary(), From::binary(), To::binary(),
+ Subject::binary(), Body::binary()) -> ok.
send_message(Type, From, To, Subject, Body) ->
CodecOpts = ejabberd_config:codec_options(),
try xmpp:decode(
diff --git a/src/mod_http_fileserver.erl b/src/mod_http_fileserver.erl
index d20d626bd..9177552a3 100644
--- a/src/mod_http_fileserver.erl
+++ b/src/mod_http_fileserver.erl
@@ -151,7 +151,9 @@ initialize(Host, Opts) ->
content_types = ContentTypes,
user_access = UserAccess}.
-%% @spec (AdminCTs::[CT], Default::[CT]) -> [CT]
+-spec build_list_content_types(AdminCTs::[{binary(), binary()|undefined}],
+ Default::[{binary(), binary()|undefined}]) ->
+ [{string(), string()|undefined}].
%% where CT = {Extension::string(), Value}
%% Value = string() | undefined
%% @doc Return a unified list without duplicates.
@@ -265,7 +267,8 @@ code_change(_OldVsn, State, _Extra) ->
%% request_handlers callbacks
%%====================================================================
-%% @spec (LocalPath, Request) -> {HTTPCode::integer(), [Header], Page::string()}
+-spec process(LocalPath::[binary()], #request{}) ->
+ {HTTPCode::integer(), [{binary(), binary()}], Page::string()}.
%% @doc Handle an HTTP request.
%% LocalPath is the part of the requested URL path that is "local to the module".
%% Returns the page to be sent back to the client and/or HTTP status code.
diff --git a/src/mod_mqtt_session.erl b/src/mod_mqtt_session.erl
index 6a551f00f..9b8c6ed44 100644
--- a/src/mod_mqtt_session.erl
+++ b/src/mod_mqtt_session.erl
@@ -436,7 +436,7 @@ upgrade_state(State) ->
upgrade_state(setelement(2, State1, VSN+1))
end.
--spec upgrade_state(tuple(), 1..?VSN) -> tuple().
+-spec upgrade_state(tuple(), integer()) -> tuple().
upgrade_state(OldState, 1) ->
%% Appending 'tls' field
erlang:append_element(OldState, false);
diff --git a/src/mod_muc_admin.erl b/src/mod_muc_admin.erl
index 891f55e96..9651cfe11 100644
--- a/src/mod_muc_admin.erl
+++ b/src/mod_muc_admin.erl
@@ -695,8 +695,7 @@ justcreated_to_binary(J) when is_atom(J) ->
%% Create/Delete Room
%%----------------------------
-%% @spec (Name::binary(), Host::binary(), ServerHost::binary()) ->
-%% ok | error
+-spec create_room(Name::binary(), Host::binary(), ServerHost::binary()) -> ok | error.
%% @doc Create a room immediately with the default options.
create_room(Name1, Host1, ServerHost) ->
create_room_with_opts(Name1, Host1, ServerHost, []).
@@ -747,8 +746,7 @@ muc_create_room(ServerHost, {Name, Host, _}, DefRoomOpts) ->
io:format("Creating room ~ts@~ts~n", [Name, Host]),
mod_muc:store_room(ServerHost, Host, Name, DefRoomOpts).
-%% @spec (Name::binary(), Host::binary()) ->
-%% ok | {error, room_not_exists}
+-spec destroy_room(Name::binary(), Host::binary()) -> ok | {error, room_not_exists}.
%% @doc Destroy the room immediately.
%% If the room has participants, they are not notified that the room was destroyed;
%% they will notice when they try to chat and receive an error that the room doesn't exist.
@@ -1116,8 +1114,8 @@ send_direct_invitation(FromJid, UserJid, Msg) ->
%% Change Room Option
%%----------------------------
-%% @spec(Name::string(), Service::string(), Option::string(), Value) -> ok
-%% Value = atom() | integer() | string()
+-spec change_room_option(Name::binary(), Service::binary(), Option::binary(),
+ Value::atom() | integer() | string()) -> ok | mod_muc_log_not_enabled.
%% @doc Change an option in an existing room.
%% Requires the name of the room, the MUC service where it exists,
%% the option to change (for example title or max_users),
diff --git a/src/mod_pubsub.erl b/src/mod_pubsub.erl
index 0aa4d1afc..2eff16bfe 100644
--- a/src/mod_pubsub.erl
+++ b/src/mod_pubsub.erl
@@ -3414,11 +3414,6 @@ node_config(Node, ServerHost, [{RE, Opts}|NodeOpts]) ->
node_config(_, _, []) ->
[].
-%% @spec (Host, Options) -> MaxItems
-%% Host = host()
-%% Options = [Option]
-%% Option = {Key::atom(), Value::term()}
-%% MaxItems = integer() | unlimited
%% @doc <p>Return the maximum number of items for a given node.</p>
%% <p>Unlimited means that there is no limit in the number of items that can
%% be stored.</p>
diff --git a/src/mod_roster_mnesia.erl b/src/mod_roster_mnesia.erl
index e42367b1f..19f602f1e 100644
--- a/src/mod_roster_mnesia.erl
+++ b/src/mod_roster_mnesia.erl
@@ -194,7 +194,6 @@ process_rosteritems(ActionS, SubsS, AsksS, UsersS, ContactsS) ->
),
rosteritem_purge({Action, Subs, Asks, Users, Contacts}).
-%% @spec ({Action::atom(), Subs::[atom()], Asks::[atom()], User::string(), Contact::string()}) -> {atomic, ok}
rosteritem_purge(Options) ->
Num_rosteritems = mnesia:table_info(roster, size),
io:format("There are ~p roster items in total.~n", [Num_rosteritems]),
diff --git a/src/mod_shared_roster.erl b/src/mod_shared_roster.erl
index 1960835a1..333a64a45 100644
--- a/src/mod_shared_roster.erl
+++ b/src/mod_shared_roster.erl
@@ -512,7 +512,8 @@ get_group_opt_cached(Host, Group, Opt, Default, Cache) ->
proplists:get_value(Opt, Opts, Default)
end.
-%% @spec (Host::string(), Group::string(), Opt::atom(), Default) -> OptValue | Default
+-spec get_group_opt(Host::binary(), Group::binary(), displayed_groups | label, Default) ->
+ OptValue::any() | Default.
get_group_opt(Host, Group, Opt, Default) ->
case get_group_opts(Host, Group) of
error -> Default;
@@ -687,7 +688,8 @@ is_user_in_group(US, Group, Host) ->
true
end.
-%% @spec (Host::string(), {User::string(), Server::string()}, Group::string()) -> {atomic, ok} | error
+-spec add_user_to_group(Host::binary(), {User::binary(), Server::binary()},
+ Group::binary()) -> {atomic, ok} | error.
add_user_to_group(Host, US, Group) ->
{_LUser, LServer} = US,
case lists:member(LServer, ejabberd_config:get_option(hosts)) of