Compare commits

...

32 Commits

Author SHA1 Message Date
Badlop ef754939c4 Set version to 25.04
CI / Tests (25) (push) Failing after 9s
CI / Tests (26) (push) Failing after 0s
CI / Tests (27) (push) Failing after 0s
Container / Container (push) Failing after 45s
Installers / Binaries (push) Failing after 50s
Runtime / Rebars (20, rebar) (push) Failing after 6s
Runtime / Rebars (20, rebar3) (push) Failing after 5s
Runtime / Rebars (25, rebar) (push) Failing after 6s
Runtime / Rebars (25, rebar3) (push) Failing after 4s
Runtime / Rebars (26, rebar) (push) Failing after 7s
Runtime / Rebars (26, rebar3) (push) Failing after 4s
Runtime / Rebars (27, rebar3) (push) Failing after 6s
Runtime / Rebar3+Elixir (1.13) (push) Failing after 7s
Runtime / Rebar3+Elixir (1.14) (push) Failing after 6s
Runtime / Rebar3+Elixir (1.15) (push) Failing after 6s
Runtime / Rebar3+Elixir (1.16) (push) Failing after 6s
Runtime / Rebar3+Elixir (1.17) (push) Failing after 7s
Runtime / Rebar3+Elixir (1.18) (push) Failing after 7s
Runtime / Mix (1.13) (push) Failing after 5s
Runtime / Mix (1.14) (push) Failing after 5s
Runtime / Mix (1.15) (push) Failing after 5s
Runtime / Mix (1.16) (push) Failing after 4s
Runtime / Mix (1.17) (push) Failing after 4s
Runtime / Mix (1.18) (push) Failing after 4s
Installers / Release (push) Has been skipped
2025-04-16 17:58:37 +02:00
Badlop ee3a0b8b1a Bump Erlang/OTP version to 27.3.2
27.3.3 was just release, but image is not yet published in
https://hub.docker.com/_/erlang/tags?name=27.3
2025-04-16 17:20:28 +02:00
Badlop 2182cb60ae CHANGELOG: Fix typos 2025-04-16 13:44:13 +02:00
Badlop 4da8278e66 Update other translations 2025-04-16 13:44:13 +02:00
Badlop 629db496b5 Update Chinese (Simplified) translation (thanks to Sketch6580) 2025-04-16 13:44:13 +02:00
Badlop f79b8e166a Update Ukrainian translation (thanks to Максим Горпиніч) 2025-04-16 13:44:13 +02:00
Badlop fae4ab97fd Update Albanian translation (thanks to Besnik Bleta) 2025-04-16 13:44:13 +02:00
Badlop da8d04a654 Update Portuguese translation (thanks to Silvério Santos) 2025-04-16 13:44:13 +02:00
Badlop ce02fc485f Update Portuguese (Brazil) translation (thanks to Wellington Uemura) 2025-04-16 13:44:13 +02:00
Badlop 69695ffe27 Update German translation (thanks to Nautilusx) 2025-04-16 13:44:13 +02:00
Badlop 6fdb467484 Update man page to 25.04 2025-04-16 13:44:13 +02:00
Badlop d8016a6477 Result of running "make format" 2025-04-16 13:44:13 +02:00
Badlop e43d864184 CI: Bump ubuntu-24.04, and Erlang 25+ (#4281)
Update postgresql preparation:
- ubuntu-20.04 included PostgreSQL 14.13
- ubuntu-24.04 includes PostgreSQL 16.4
and in the meantime, PostgreSQL 15.0 revoked
"the CREATE permission from all users except a database owner from the public (or default) schema."
See https://www.postgresql.org/about/news/postgresql-15-released-2526/
2025-04-16 13:44:07 +02:00
Badlop 4d3681aba1 Annotate kick_users version 2025-04-16 13:43:13 +02:00
Paweł Chmielowski d791f6ceaa Update changelog 2025-04-16 12:56:04 +02:00
Paweł Chmielowski 602a42f5ce Add tests for duplicate occupant-id handling 2025-04-16 11:39:30 +02:00
Paweł Chmielowski c98739d5b5 Replace all occupand_id tags 2025-04-14 16:42:00 +02:00
Paweł Chmielowski 425504454c Allow passing multiple paths in external_beams 2025-04-08 14:21:18 +02:00
Paweł Chmielowski 780031847c Relax limits of shared groups names
We want to normalize it, but we don't need to limit it to what nodeprep
allows (like for example ':' that we see in use)
2025-04-04 11:07:51 +02:00
Paweł Chmielowski c3af613db1 Catch errors from mod_shared_roster:create_group in srg_* commands 2025-04-04 11:07:51 +02:00
Badlop babd01a87f Container: Improve explanation of CTL_ON ignore prefix 2025-04-03 13:43:15 +02:00
Badlop 17b605a32b kick_users command: Move to "Online Users" page, disable auto-execution
kick_users can be considered a "modifier" command with "informative" result
as described in include/ejabberd_commands.hrl

ejabberd_web_admin executes automatically a command if:
- it returns something different than rescode or restuple
- and all its arguments are provided
- and force_execution is set to true or undefined
2025-04-03 13:43:13 +02:00
badlop fc813acd7b Merge pull request #4364 from Quobis/ejabberdctl-kick_users-command
ejabberdctl: add new `kick_users host` command
2025-04-03 12:56:53 +02:00
Badlop d842d6772d CI: Pull Redis image from ECR instead of Docker Hub
Pull images from Amazon ECR (Elastic Container Registry) Public Gallery
instead of Docker Hub to reduce consumption of the pull limits
https://www.docker.com/blog/revisiting-docker-hub-policies-prioritizing-developer-experience/
2025-04-01 16:07:46 +02:00
Badlop 67aaf93157 Runtime: Pull images from ECR instead of Docker Hub
Pull images from Amazon ECR (Elastic Container Registry) Public Gallery
instead of Docker Hub to reduce consumption of the pull limits
https://www.docker.com/blog/revisiting-docker-hub-policies-prioritizing-developer-experience/
2025-04-01 13:42:22 +02:00
Badlop 9154275431 Revert "build(deps): bump stun from 1.2.17 to 1.2.19"
This reverts commit a8a5be7a34.

Don't upgrade to stun 1.2.19 yet, because esip still depends on stun 1.2.17:

Because "the lock" depends on "esip 1.0.57" which depends on "stun 1.2.17", "the lock" requires "stun 1.2.17".
And because "the lock" specifies "stun 1.2.19", no version of "the lock" is allowed.
So, because "your app" depends on "the lock", version solving failed.
** (Mix) Hex dependency resolution failed
2025-04-01 13:42:22 +02:00
Badlop c343ef7aad Container: Apply recent ejabberdctl backward support code 2025-04-01 13:42:22 +02:00
Badlop 78093735b7 ejabberdctl: Add backward support for mnesia path with nodename (#4366) 2025-04-01 12:35:51 +02:00
dependabot[bot] ed6a111982 build(deps): bump XMPP-Interop-Testing/xmpp-interop-tests-action
Bumps [XMPP-Interop-Testing/xmpp-interop-tests-action](https://github.com/xmpp-interop-testing/xmpp-interop-tests-action) from 1.4.0 to 1.5.0.
- [Commits](https://github.com/xmpp-interop-testing/xmpp-interop-tests-action/compare/v1.4.0...v1.5.0)

---
updated-dependencies:
- dependency-name: XMPP-Interop-Testing/xmpp-interop-tests-action
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 12:35:47 +02:00
dependabot[bot] a8a5be7a34 build(deps): bump stun from 1.2.17 to 1.2.19
Bumps [stun](https://github.com/processone/stun) from 1.2.17 to 1.2.19.
- [Changelog](https://github.com/processone/stun/blob/master/CHANGELOG.md)
- [Commits](https://github.com/processone/stun/compare/1.2.17...1.2.19)

---
updated-dependencies:
- dependency-name: stun
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-01 12:35:44 +02:00
Paweł Chmielowski 5008947e32 Make sqlite update_primary_key when copying data use list of columns and not *
Since * depends on order of columns, if original table have different
column layout we could get resulting columns in wrong order.

This is fix for issue #4365
2025-03-31 11:49:30 +02:00
Marcos de Vera Piquero 0827a5116f ejabberdctl: add new kick_users host command
This new command accepts a host name and will kick all user sessions
found for that given host. The result is the number of kicked
sessions.
2025-03-28 17:45:54 +01:00
34 changed files with 258 additions and 83 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
#' Define default build variables
ARG OTP_VSN='27.3'
ARG OTP_VSN='27.3.2'
ARG ELIXIR_VSN='1.18.3'
ARG UID='9000'
ARG USER='ejabberd'
+4
View File
@@ -71,6 +71,10 @@ done
: "${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
+8 -16
View File
@@ -25,11 +25,11 @@ jobs:
strategy:
fail-fast: false
matrix:
otp: ['20.0', '25', '26', '27']
runs-on: ubuntu-20.04
otp: ['25', '26', '27']
runs-on: ubuntu-24.04
services:
redis:
image: redis
image: public.ecr.aws/docker/library/redis
ports:
- 6379:6379
@@ -50,13 +50,6 @@ jobs:
with:
otp-version: ${{ matrix.otp }}
- name: Get a compatible Rebar3
if: matrix.otp < 24
run: |
rm rebar3
wget https://github.com/processone/ejabberd/raw/21.12/rebar3
chmod +x rebar3
- name: Install MS SQL Server
run: |
docker run -d -e "ACCEPT_EULA=Y" -e "SA_PASSWORD=ejabberd_Test1" \
@@ -83,6 +76,8 @@ jobs:
WITH PASSWORD 'ejabberd_test';"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES
ON DATABASE ejabberd_test TO ejabberd_test;"
sudo -u postgres psql -c "GRANT ALL ON SCHEMA public TO ejabberd_test;"
sudo -u postgres psql -c "ALTER DATABASE ejabberd_test OWNER TO ejabberd_test;"
sudo -u postgres psql ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL
TABLES IN SCHEMA public
TO ejabberd_test;"
@@ -107,10 +102,6 @@ jobs:
~/.cache/rebar3/
key: ${{matrix.otp}}-${{hashFiles('rebar.config')}}
- name: Get old eredis for old Erlang
if: matrix.otp < 21
run: ./rebar3 unlock eredis
- name: Compile
run: |
./autogen.sh
@@ -129,7 +120,6 @@ jobs:
- run: make dialyzer
- run: make test-eunit
- run: make elvis
if: matrix.otp >= 23
- name: Check Production Release
run: |
@@ -155,7 +145,7 @@ jobs:
- name: Run XMPP Interoperability Tests against CI server.
if: matrix.otp == '27'
continue-on-error: true
uses: XMPP-Interop-Testing/xmpp-interop-tests-action@v1.4.0
uses: XMPP-Interop-Testing/xmpp-interop-tests-action@v1.5.0
with:
domain: 'localhost'
adminAccountUsername: 'admin'
@@ -267,6 +257,8 @@ jobs:
sudo -u postgres psql -c "CREATE DATABASE ejabberd_test;"
sudo -u postgres psql -c "GRANT ALL PRIVILEGES
ON DATABASE ejabberd_test TO ejabberd_test;"
sudo -u postgres psql -c "GRANT ALL ON SCHEMA public TO ejabberd_test;"
sudo -u postgres psql -c "ALTER DATABASE ejabberd_test OWNER TO ejabberd_test;"
sudo -u postgres psql ejabberd_test -c "GRANT ALL PRIVILEGES ON ALL
TABLES IN SCHEMA public
TO ejabberd_test;"
+3 -3
View File
@@ -38,7 +38,7 @@ jobs:
rebar: 'rebar'
runs-on: ubuntu-24.04
container:
image: erlang:${{ matrix.otp }}
image: public.ecr.aws/docker/library/erlang:${{ matrix.otp }}
steps:
@@ -167,7 +167,7 @@ jobs:
elixir: ['1.13', '1.14', '1.15', '1.16', '1.17', '1.18']
runs-on: ubuntu-24.04
container:
image: elixir:${{ matrix.elixir }}
image: public.ecr.aws/docker/library/elixir:${{ matrix.elixir }}
steps:
@@ -290,7 +290,7 @@ jobs:
elixir: ['1.13', '1.14', '1.15', '1.16', '1.17', '1.18']
runs-on: ubuntu-24.04
container:
image: elixir:${{ matrix.elixir }}
image: public.ecr.aws/docker/library/elixir:${{ matrix.elixir }}
steps:
+16
View File
@@ -1,3 +1,19 @@
## Version 25.04
#### Security fixes
- Fixes issue with handling of user provided occupant-id in messages and presences sent to muc room. Server was replacing
just first instance of occupant-id with its own version, leaving other ones untouched. That would mean that depending
on order in which clients send occupant-id, they could see value provided by sender, and that could be used to spoof
as different sender.
#### Commands API
- `kick_users`: New command to kick all logged users for a given host
#### Bugfixes
- Fix issue with sql schema auto upgrade when using `sqlite` database
- Fix problem with container update, that could ignore previous data stored in `mnesia` database
- Revert limit of allowed characters in shared roster group names, that will again allow using symbols like `:`
## Version 25.03
#### Commands API
+11 -5
View File
@@ -266,15 +266,21 @@ and reads `CTL_ON_START` every time the container is started.
Those variables can contain one ejabberdctl command,
or several commands separated with the blankspace and `;` characters.
By default failure of any of commands executed that way would
abort start, this can be disabled by prefixing commands with `!`
If any of those commands returns a failure, the container starting gets aborted.
If there is a command with a result that can be ignored,
prefix that command with `!`
Example usage (or check the [full example](#customized-example)):
This example, registers an `admin@localhost` account when the container is first created.
Everytime the container starts, it shows the list of registered accounts,
checks that the admin account exists and password is valid,
changes the password of an account if it exists (ignoring any failure),
and shows the ejabberd starts (check also the [full example](#customized-example)):
```yaml
environment:
- CTL_ON_CREATE=! register admin localhost asd
- CTL_ON_CREATE=register admin localhost asd
- CTL_ON_START=stats registeredusers ;
check_password admin localhost asd ;
! change_password bot123 localhost qqq ;
status
```
@@ -920,7 +926,7 @@ Let's summarize the differences between both container images. Legend:
| Generated by | [container.yml](https://github.com/processone/ejabberd/blob/master/.github/workflows/container.yml) | [tests.yml](https://github.com/processone/docker-ejabberd/blob/master/.github/workflows/tests.yml) |
| Built for | stable releases <br /> `master` branch | stable releases <br /> [`master` branch zip](https://github.com/processone/docker-ejabberd/actions/workflows/tests.yml) |
| Architectures | `linux/amd64` <br /> `linux/arm64` | `linux/amd64` |
| Software | Erlang/OTP 27.3-alpine <br /> Elixir 1.18.3 | Alpine 3.19 <br /> Erlang/OTP 26.2 <br /> Elixir 1.15.7 |
| Software | Erlang/OTP 27.3.2-alpine <br /> Elixir 1.18.3 | Alpine 3.19 <br /> Erlang/OTP 26.2 <br /> Elixir 1.15.7 |
| Published in | [ghcr.io/processone/ejabberd](https://github.com/processone/ejabberd/pkgs/container/ejabberd) | [docker.io/ejabberd/ecs](https://hub.docker.com/r/ejabberd/ecs/) <br /> [ghcr.io/processone/ecs](https://github.com/processone/docker-ejabberd/pkgs/container/ecs) |
| :black_square_button: **Additional content** |
| [ejabberd-contrib](https://docs.ejabberd.im/admin/guide/modules/#ejabberd-contrib) | included | not included |
+1 -1
View File
@@ -2,7 +2,7 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo 25.03` | sed 's/-g.*//;s/-/./' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd])
AC_INIT(ejabberd, m4_esyscmd([echo `git describe --tags 2>/dev/null || echo 25.04` | sed 's/-g.*//;s/-/./' | tr -d '\012']), [ejabberd@process-one.net], [ejabberd])
REQUIRE_ERLANG_MIN="9.0.5 (Erlang/OTP 20.0)"
REQUIRE_ERLANG_MAX="100.0.0 (No Max)"
+4
View File
@@ -71,6 +71,10 @@ done
: "${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
+16 -16
View File
@@ -2,12 +2,12 @@
.\" Title: ejabberd.yml
.\" Author: [see the "AUTHOR" section]
.\" Generator: DocBook XSL Stylesheets vsnapshot <http://docbook.sf.net/>
.\" Date: 03/28/2025
.\" Date: 04/16/2025
.\" Manual: \ \&
.\" Source: \ \&
.\" Language: English
.\"
.TH "EJABBERD\&.YML" "5" "03/28/2025" "\ \&" "\ \&"
.TH "EJABBERD\&.YML" "5" "04/16/2025" "\ \&" "\ \&"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -82,12 +82,12 @@ 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/25\&.03/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\&.04/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 25\&.03\&. The options that changed in this version are marked with 🟤\&.
This section describes top level options of ejabberd 25\&.04\&. The options that changed in this version are marked with 🟤\&.
.PP
\fBaccess_rules\fR: \fI{AccessName: {allow|deny: ACLName|ACLDefinition}}\fR
.RS 4
@@ -469,7 +469,7 @@ format\&. You shouldn\(cqt change this if you already have passwords generated w
\fIsha\fR\&.
.RE
.PP
\fBauth_stored_password_types 🟤\fR: \fI[plain | scram_sha1 | scram_sha256 | scram_sha512]\fR
\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
@@ -707,7 +707,7 @@ Default volatile (in\-memory) storage for ejabberd\&. Modules and other componen
\fImnesia\fR\&.
.RE
.PP
\fBdefine_keyword 🟤\fR: \fI{NAME: Value}\fR
\fBdefine_keyword\fR: \fI{NAME: Value}\fR
.RS 4
\fINote\fR
about this option: added in 25\&.03\&. Allows to define configuration
@@ -734,7 +734,7 @@ sql_username: "prefix\&.@SQL_USERNAME@"
.\}
.RE
.PP
\fBdefine_macro 🟤\fR: \fI{NAME: Value}\fR
\fBdefine_macro\fR: \fI{NAME: Value}\fR
.RS 4
\fINote\fR
about this option: improved in 25\&.03\&. Allows to define configuration
@@ -1246,7 +1246,7 @@ This option can be used to tune tick time parameter of
.RS 4
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\&.03/sql\&. There are two schemas available\&. The default legacy schema stores one XMPP domain into one ejabberd database\&. The
https://github\&.com/processone/ejabberd/tree/25\&.04/sql\&. There are two schemas available\&. The default legacy schema stores one XMPP domain into one ejabberd database\&. The
\fInew\fR
schema can handle several XMPP domains in a single ejabberd database\&. Using this
\fInew\fR
@@ -2043,7 +2043,7 @@ seconds\&.
.RE
.SH "MODULES"
.sp
This section describes modules options of ejabberd 25\&.03\&. The modules that changed in this version are marked with 🟤\&.
This section describes modules options of ejabberd 25\&.04\&. The modules that changed in this version are marked with 🟤\&.
.SS "mod_adhoc"
.sp
This module implements XEP\-0050: Ad\-Hoc Commands\&. It\(cqs an auxiliary module and is only needed by some of the other modules\&.
@@ -2062,7 +2062,7 @@ Provide the Commands item in the Service Discovery\&. Default value:
\fIfalse\fR\&.
.RE
.RE
.SS "mod_adhoc_api 🟤"
.SS "mod_adhoc_api"
.sp
\fINote\fR about this option: added in 25\&.03\&.
.sp
@@ -2808,7 +2808,7 @@ Please notice that all the ad\-hoc commands implemented by this module have an e
\fBAvailable options:\fR
.RS 4
.PP
\fBaccess 🟤\fR: \fIAccessName\fR
\fBaccess\fR: \fIAccessName\fR
.RS 4
\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
@@ -3956,7 +3956,7 @@ When this option is disabled, for each individual subscriber a separate mucsub m
\fIfalse\fR\&.
.RE
.RE
.SS "mod_matrix_gw 🟤"
.SS "mod_matrix_gw"
.sp
\fINote\fR about this option: improved in 25\&.03\&.
.sp
@@ -4629,7 +4629,7 @@ in order to accept their join in the room\&. The default value is
Short description of the room\&. The default value is an empty string\&.
.RE
.PP
\fBenable_hats 🟤\fR: \fItrue | false\fR
\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
@@ -8372,7 +8372,7 @@ Should the operating system be revealed or not\&. The default value is
.RE
.SH "LISTENERS"
.sp
This section describes listeners options of ejabberd 25\&.03\&.
This section describes listeners options of ejabberd 25\&.04\&.
.sp
TODO
.SH "AUTHOR"
@@ -8380,13 +8380,13 @@ TODO
ProcessOne\&.
.SH "VERSION"
.sp
This document describes the configuration file of ejabberd 25\&.03\&. Configuration options of other ejabberd versions may differ significantly\&.
This document describes the configuration file of ejabberd 25\&.04\&. Configuration options of other ejabberd versions may differ significantly\&.
.SH "REPORTING BUGS"
.sp
Report bugs to https://github\&.com/processone/ejabberd/issues
.SH "SEE ALSO"
.sp
Default configuration file: https://github\&.com/processone/ejabberd/blob/25\&.03/ejabberd\&.yml\&.example
Default configuration file: https://github\&.com/processone/ejabberd/blob/25\&.04/ejabberd\&.yml\&.example
.sp
Main site: https://ejabberd\&.im
.sp
+5
View File
@@ -46,7 +46,9 @@
{"Anyone with a presence subscription of both or from may subscribe and retrieve items","Qualsevol amb una subscripció de presencia de 'both' o 'from' pot subscriure's i publicar elements"}.
{"Anyone with Voice","Qualsevol amb Veu"}.
{"Anyone","Qualsevol"}.
{"API Commands","Comandaments API"}.
{"April","Abril"}.
{"Arguments","Arguments"}.
{"Attribute 'channel' is required for this request","L'atribut 'channel' és necessari per a aquesta petició"}.
{"Attribute 'id' is mandatory for MIX messages","L'atribut 'id' es necessari per a missatges MIX"}.
{"Attribute 'jid' is not allowed here","L'atribut 'jid' no està permès ací"}.
@@ -86,6 +88,7 @@
{"Choose whether to approve this entity's subscription.","Tria si aproves aquesta entitat de subscripció."}.
{"City","Ciutat"}.
{"Client acknowledged more stanzas than sent by server","El client ha reconegut més paquets dels que ha enviat el servidor"}.
{"Clustering","Clustering"}.
{"Commands","Comandaments"}.
{"Conference room does not exist","La sala de conferències no existeix"}.
{"Configuration of room ~s","Configuració de la sala ~s"}.
@@ -408,6 +411,7 @@
{"Restore binary backup immediately:","Restaurar una còpia de seguretat binària ara mateix:"}.
{"Restore plain text backup immediately:","Restaurar una còpia de seguretat en format de text pla ara mateix:"}.
{"Restore","Restaurar"}.
{"Result","Resultat"}.
{"Roles and Affiliations that May Retrieve Member List","Rols i Afiliacions que poden recuperar la llista de membres"}.
{"Roles for which Presence is Broadcasted","Rols per als que sí se difon la seua presencia"}.
{"Roles that May Send Private Messages","Rols que poden enviar missatges privats"}.
@@ -584,6 +588,7 @@
{"Visitor","Visitant"}.
{"Voice request","Petició de veu"}.
{"Voice requests are disabled in this conference","Les peticions de veu es troben desactivades en aquesta conferència"}.
{"Web client which allows to join the room anonymously","Client web que permet entrar a la sala anonimament"}.
{"Wednesday","Dimecres"}.
{"When a new subscription is processed and whenever a subscriber comes online","Quan es processa una nova subscripció i un subscriptor es connecta"}.
{"When a new subscription is processed","Quan es processa una nova subscripció"}.
+6
View File
@@ -46,7 +46,9 @@
{"Anyone with a presence subscription of both or from may subscribe and retrieve items","Jeder mit einem Präsenzabonnement von beiden oder davon darf Items abonnieren oder abrufen"}.
{"Anyone with Voice","Jeder mit Stimme"}.
{"Anyone","Jeder"}.
{"API Commands","API Befehle"}.
{"April","April"}.
{"Arguments","Argumente"}.
{"Attribute 'channel' is required for this request","Attribut 'channel' ist für diese Anforderung erforderlich"}.
{"Attribute 'id' is mandatory for MIX messages","Attribut 'id' ist verpflichtend für MIX-Nachrichten"}.
{"Attribute 'jid' is not allowed here","Attribut 'jid' ist hier nicht erlaubt"}.
@@ -168,6 +170,7 @@
{"has been kicked because of an affiliation change","wurde wegen einer Änderung der Zugehörigkeit hinausgeworfen"}.
{"has been kicked because the room has been changed to members-only","wurde hinausgeworfen weil der Raum zu Nur-Mitglieder geändert wurde"}.
{"has been kicked","wurde hinausgeworfen"}.
{"Hash of the vCard-temp avatar of this room","Hash des vCard-temp Avatars dieses Raums"}.
{"Hat title","Funktionstitel"}.
{"Hat URI","Funktions-URI"}.
{"Hats limit exceeded","Funktionslimit wurde überschritten"}.
@@ -406,6 +409,7 @@
{"Restore binary backup immediately:","Stelle binäres Backup sofort wieder her:"}.
{"Restore plain text backup immediately:","Stelle Klartext-Backup sofort wieder her:"}.
{"Restore","Wiederherstellung"}.
{"Result","Ergebnis"}.
{"Roles and Affiliations that May Retrieve Member List","Rollen und Zugehörigkeiten die Mitgliederliste abrufen dürfen"}.
{"Roles for which Presence is Broadcasted","Rollen für welche die Präsenz übertragen wird"}.
{"Roles that May Send Private Messages","Rollen die Privatnachrichten senden dürfen"}.
@@ -550,6 +554,7 @@
{"Update message of the day on all hosts (don't send)","Aktualisiere Nachricht des Tages auf allen Hosts (nicht senden)"}.
{"Update specs to get modules source, then install desired ones.","Aktualisieren Sie die Spezifikationen, um den Quellcode der Module zu erhalten und installieren Sie dann die gewünschten Module."}.
{"Update Specs","Spezifikationen aktualisieren"}.
{"Updating the vCard is not supported by the vCard storage backend","Aktualisierung der vCard wird vom vCard-Speicher-Backend nicht unterstützt"}.
{"Upgrade","Upgrade"}.
{"URL for Archived Discussion Logs","URL für archivierte Diskussionsprotokolle"}.
{"User already exists","Benutzer existiert bereits"}.
@@ -578,6 +583,7 @@
{"Visitors are not allowed to send messages to all occupants","Besucher dürfen nicht an alle Teilnehmer Nachrichten versenden"}.
{"Voice requests are disabled in this conference","Sprachrecht-Anforderungen sind in diesem Raum deaktiviert"}.
{"Voice request","Sprachrecht-Anforderung"}.
{"Web client which allows to join the room anonymously","Web-Client, der es ermöglicht, dem Raum anonym beizutreten"}.
{"Wednesday","Mittwoch"}.
{"When a new subscription is processed and whenever a subscriber comes online","Sobald ein neues Abonnement verarbeitet wird und wann immer ein Abonnent sich anmeldet"}.
{"When a new subscription is processed","Sobald ein neues Abonnement verarbeitet wird"}.
+6 -1
View File
@@ -46,7 +46,9 @@
{"Anyone with a presence subscription of both or from may subscribe and retrieve items","Cualquiera con una suscripción a la presencia de 'ambos' o 'de' puede suscribirse y recibir elementos"}.
{"Anyone with Voice","Cualquiera con Voz"}.
{"Anyone","Cualquiera"}.
{"API Commands","Comandos API"}.
{"April","Abril"}.
{"Arguments","Argumentos"}.
{"Attribute 'channel' is required for this request","El atributo 'channel' es necesario para esta petición"}.
{"Attribute 'id' is mandatory for MIX messages","El atributo 'id' es necesario para mensajes MIX"}.
{"Attribute 'jid' is not allowed here","El atributo 'jid' no está permitido aqui"}.
@@ -86,6 +88,7 @@
{"Choose whether to approve this entity's subscription.","Decidir si aprobar la subscripción de esta entidad."}.
{"City","Ciudad"}.
{"Client acknowledged more stanzas than sent by server","El cliente ha reconocido más paquetes de los que el servidor ha enviado"}.
{"Clustering","Clustering"}.
{"Commands","Comandos"}.
{"Conference room does not exist","La sala de conferencias no existe"}.
{"Configuration of room ~s","Configuración para la sala ~s"}.
@@ -161,7 +164,7 @@
{"Get Pending","Obtener pendientes"}.
{"Get User Last Login Time","Ver fecha de la última conexión de usuario"}.
{"Get User Statistics","Ver estadísticas de usuario"}.
{"Given Name","Nombre"}.
{"Given Name","Nombre de pila"}.
{"Grant voice to this person?","¿Conceder voz a esta persona?"}.
{"has been banned","ha sido bloqueado"}.
{"has been kicked because of a system shutdown","ha sido expulsado porque el sistema se va a detener"}.
@@ -408,6 +411,7 @@
{"Restore binary backup immediately:","Restaurar inmediatamente copia de seguridad binaria:"}.
{"Restore plain text backup immediately:","Restaurar copias de seguridad de texto plano inmediatamente:"}.
{"Restore","Restaurar"}.
{"Result","Resultado"}.
{"Roles and Affiliations that May Retrieve Member List","Roles y Afiliaciones que pueden obtener la lista de miembros"}.
{"Roles for which Presence is Broadcasted","Roles para los que sí se difunde su Presencia"}.
{"Roles that May Send Private Messages","Roles que pueden enviar mensajes privados"}.
@@ -584,6 +588,7 @@
{"Visitor","Visitante"}.
{"Voice request","Petición de voz"}.
{"Voice requests are disabled in this conference","Las peticiones de voz están desactivadas en esta sala"}.
{"Web client which allows to join the room anonymously","Cliente web que permite entrar en la sala anonimamente"}.
{"Wednesday","Miércoles"}.
{"When a new subscription is processed and whenever a subscriber comes online","Cuando se procesa una nueva suscripción y cuando un suscriptor se conecta"}.
{"When a new subscription is processed","Cuando se procesa una nueva suscripción"}.
+5
View File
@@ -46,7 +46,9 @@
{"Anyone with a presence subscription of both or from may subscribe and retrieve items","Qualquer pessoa com uma assinatura presente dos dois ou de ambos pode se inscrever e recuperar os itens"}.
{"Anyone with Voice","Qualquer pessoa com voz"}.
{"Anyone","Qualquer pessoa"}.
{"API Commands","Comandos API"}.
{"April","Abril"}.
{"Arguments","Argumentos"}.
{"Attribute 'channel' is required for this request","O atributo 'canal' é necessário para esta solicitação"}.
{"Attribute 'id' is mandatory for MIX messages","O atributo 'id' é obrigatório para mensagens MIX"}.
{"Attribute 'jid' is not allowed here","O atributo 'jid' não é permitido aqui"}.
@@ -86,6 +88,7 @@
{"Choose whether to approve this entity's subscription.","Aprovar esta assinatura."}.
{"City","Cidade"}.
{"Client acknowledged more stanzas than sent by server","O cliente reconheceu mais estrofes do que as enviadas pelo servidor"}.
{"Clustering","Agrupamento"}.
{"Commands","Comandos"}.
{"Conference room does not exist","A sala de conferência não existe"}.
{"Configuration of room ~s","Configuração para ~s"}.
@@ -408,6 +411,7 @@
{"Restore binary backup immediately:","Restaurar imediatamente o backup binário:"}.
{"Restore plain text backup immediately:","Restaurar backup formato texto imediatamente:"}.
{"Restore","Restaurar"}.
{"Result","Resultado"}.
{"Roles and Affiliations that May Retrieve Member List","As funções e as afiliações que podem recuperar a lista dos membros"}.
{"Roles for which Presence is Broadcasted","Para quem a presença será notificada"}.
{"Roles that May Send Private Messages","Atribuições que talvez possam enviar mensagens privadas"}.
@@ -584,6 +588,7 @@
{"Visitor","Visitante"}.
{"Voice request","Requisição de voz"}.
{"Voice requests are disabled in this conference","Requisições de voz estão desabilitadas nesta sala de conferência"}.
{"Web client which allows to join the room anonymously","Cliente da web que permite entrar na sala de forma anônima"}.
{"Wednesday","Quarta"}.
{"When a new subscription is processed and whenever a subscriber comes online","Quando uma nova assinatura é processada e sempre que um assinante fica online"}.
{"When a new subscription is processed","Quando uma nova assinatura é processada"}.
+11
View File
@@ -46,7 +46,9 @@
{"Anyone with a presence subscription of both or from may subscribe and retrieve items","Qualquer pessoa com uma assinatura presente dos dois ou de ambos pode se inscrever e recuperar os itens"}.
{"Anyone with Voice","Qualquer pessoa com voz"}.
{"Anyone","Qualquer pessoa"}.
{"API Commands","Comandos API"}.
{"April","Abril"}.
{"Arguments","Argumentos"}.
{"Attribute 'channel' is required for this request","O atributo 'canal' é necessário para esta solicitação"}.
{"Attribute 'id' is mandatory for MIX messages","O atributo 'id' é obrigatório para mensagens MIX"}.
{"Attribute 'jid' is not allowed here","O atributo 'jid' não é permitido aqui"}.
@@ -86,6 +88,7 @@
{"Choose whether to approve this entity's subscription.","Aprovar esta assinatura."}.
{"City","Cidade"}.
{"Client acknowledged more stanzas than sent by server","O cliente reconheceu mais estrofes do que as enviadas pelo servidor"}.
{"Clustering","Agrupamento"}.
{"Commands","Comandos"}.
{"Conference room does not exist","A sala não existe"}.
{"Configuration of room ~s","Configuração para ~s"}.
@@ -168,6 +171,7 @@
{"has been kicked because of an affiliation change","foi desconectado porque por afiliação inválida"}.
{"has been kicked because the room has been changed to members-only","foi desconectado porque a política da sala mudou, só membros são permitidos"}.
{"has been kicked","foi removido"}.
{"Hash of the vCard-temp avatar of this room","Hash do avatar do vCard-temp desta sala"}.
{"Hat title","Título do chapéu"}.
{"Hat URI","URI do chapéu"}.
{"Hats limit exceeded","O limite dos chapéus foi excedido"}.
@@ -223,6 +227,7 @@
{"leaves the room","Sair da sala"}.
{"List of users with hats","Lista os utilizadores com chapéus"}.
{"List users with hats","Lista os utilizadores com chapéus"}.
{"Logged Out","Desconectado"}.
{"Logging","Registando no log"}.
{"Make participants list public","Tornar pública a lista de participantes"}.
{"Make room CAPTCHA protected","Tornar protegida a palavra-passe da sala"}.
@@ -406,6 +411,7 @@
{"Restore binary backup immediately:","Restaurar imediatamente o backup binário:"}.
{"Restore plain text backup immediately:","Restaurar backup formato texto imediatamente:"}.
{"Restore","Restaurar"}.
{"Result","Resultado"}.
{"Roles and Affiliations that May Retrieve Member List","As funções e as afiliações que podem recuperar a lista dos membros"}.
{"Roles for which Presence is Broadcasted","Para quem a presença será notificada"}.
{"Roles that May Send Private Messages","Atribuições que talvez possam enviar mensagens privadas"}.
@@ -437,6 +443,7 @@
{"Set message of the day on all hosts and send to online users","Definir mensagem do dia em todos os hosts e enviar para os utilizadores online"}.
{"Shared Roster Groups","Grupos Shared Roster"}.
{"Show Integral Table","Mostrar Tabela Integral"}.
{"Show Occupants Join/Leave","Mostrar a entrada e a saída de ocupantes"}.
{"Show Ordinary Table","Mostrar Tabela Ordinária"}.
{"Shut Down Service","Parar Serviço"}.
{"SOCKS5 Bytestreams","Bytestreams SOCKS5"}.
@@ -534,6 +541,7 @@
{"Too many unacked stanzas","Quantidade excessiva de instâncias sem confirmação"}.
{"Too many users in this conference","Há uma quantidade excessiva de utilizadores nesta conferência"}.
{"Traffic rate limit is exceeded","Limite de banda excedido"}.
{"~ts's MAM Archive","Arquivo ~ts's MAM"}.
{"~ts's Offline Messages Queue","~s's Fila de Mensagens Offline"}.
{"Tuesday","Terça"}.
{"Unable to generate a CAPTCHA","Impossível gerar um CAPTCHA"}.
@@ -550,12 +558,14 @@
{"Update message of the day on all hosts (don't send)","Atualizar a mensagem do dia em todos os host (não enviar)"}.
{"Update specs to get modules source, then install desired ones.","Atualize as especificações para obter a fonte dos módulos e instale os que desejar."}.
{"Update Specs","Atualizar as especificações"}.
{"Updating the vCard is not supported by the vCard storage backend","A atualização do vCard não é compatível com o back-end de armazenamento do vCard"}.
{"Upgrade","Atualização"}.
{"URL for Archived Discussion Logs","A URL para o arquivamento dos registos da discussão"}.
{"User already exists","Utilizador já existe"}.
{"User (jid)","Utilizador (jid)"}.
{"User JID","Utilizador JID"}.
{"User Management","Gestão de utilizadores"}.
{"User not allowed to perform an IQ set on another user's vCard.","O utilizador não tem permissão para executar um conjunto de QI no vCard de outro utilizador."}.
{"User removed","O utilizador foi removido"}.
{"User session not found","A sessão do utilizador não foi encontrada"}.
{"User session terminated","Sessão de utilizador terminada"}.
@@ -578,6 +588,7 @@
{"Visitor","Visitante"}.
{"Voice request","Requisição de voz"}.
{"Voice requests are disabled in this conference","Requisições de voz estão desativadas nesta sala de conferência"}.
{"Web client which allows to join the room anonymously","Cliente da web que permite entrar na sala de forma anônima"}.
{"Wednesday","Quarta"}.
{"When a new subscription is processed and whenever a subscriber comes online","Quando uma nova assinatura é processada e sempre que um assinante fica online"}.
{"When a new subscription is processed","Quando uma nova assinatura é processada"}.
+2
View File
@@ -28,7 +28,9 @@
{"Anyone may publish","Gjithkush mund të publikojë"}.
{"Anyone with Voice","Cilido me Zë"}.
{"Anyone","Cilido"}.
{"API Commands","Urdhra API"}.
{"April","Prill"}.
{"Arguments","Argumente"}.
{"Attribute 'channel' is required for this request","Atributi 'channel' është i domosdoshëm për këtë kërkesë"}.
{"Attribute 'jid' is not allowed here","Atributi 'jid' slejohet këtu"}.
{"Attribute 'node' is not allowed here","Atributi 'node' slejohet këtu"}.
-2
View File
@@ -34,7 +34,6 @@
{"Chatrooms","Chattrum"}.
{"Choose a username and password to register with this server","Välj ett användarnamn och lösenord för att registrera mot denna server"}.
{"Choose storage type of tables","Välj lagringstyp för tabeller"}.
{"Choose whether to approve this entity's subscription.","Välj om du vill godkänna hela denna prenumertion."}.
{"City","Stad"}.
{"Commands","Kommandon"}.
{"Conference room does not exist","Rummet finns inte"}.
@@ -196,7 +195,6 @@
{"Search users in ","Sök efter användare på "}.
{"Send announcement to all online users on all hosts","Sänd meddelanden till alla inloggade användare på alla värdar"}.
{"Send announcement to all online users","Sänd meddelanden till alla inloggade användare"}.
{"Send announcement to all users on all hosts","Sänd meddelanden till alla användare på alla värdar"}.
{"Send announcement to all users","Sänd meddelanden till alla användare"}.
{"September","September"}.
{"Set message of the day and send to online users","Sätt dagens status meddelande och skicka till alla användare"}.
+5
View File
@@ -46,7 +46,9 @@
{"Anyone with a presence subscription of both or from may subscribe and retrieve items","Будь-хто, хто має підписку на отримання інформації про присутність в обох випадках або може підписуватись та отримувати матеріали"}.
{"Anyone with Voice","Будь-хто, хто має голос"}.
{"Anyone","Будь-хто"}.
{"API Commands","Команди API"}.
{"April","Квітень"}.
{"Arguments","Аргументи"}.
{"Attribute 'channel' is required for this request","Атрибут \"канал\" є обов'язковим для цього запиту"}.
{"Attribute 'id' is mandatory for MIX messages","Атрибут 'id' обов'язковий для MIX повідомлень"}.
{"Attribute 'jid' is not allowed here","Атрибут 'jid' заборонений"}.
@@ -86,6 +88,7 @@
{"Choose whether to approve this entity's subscription.","Виберіть, чи підтверджувати підписку."}.
{"City","Місто"}.
{"Client acknowledged more stanzas than sent by server","Клієнт підтвердив більше повідомлень, ніж було відправлено сервером"}.
{"Clustering","Кластеризація"}.
{"Commands","Команди"}.
{"Conference room does not exist","Кімната для переговорів відсутня"}.
{"Configuration of room ~s","Конфігурація кімнати ~s"}.
@@ -408,6 +411,7 @@
{"Restore binary backup immediately:","Відновити з бінарної резервної копії негайно:"}.
{"Restore plain text backup immediately:","Відновити з текстової резервної копії негайно:"}.
{"Restore","Відновлення з резервної копії"}.
{"Result","Результат"}.
{"Roles and Affiliations that May Retrieve Member List","Ролі та зв’язки, які можуть отримати список учасників"}.
{"Roles for which Presence is Broadcasted","Ролі для яких поширюється наявність"}.
{"Roles that May Send Private Messages","Ролі, що можуть надсилати приватні повідомлення"}.
@@ -584,6 +588,7 @@
{"Visitor","Відвідувач"}.
{"Voice requests are disabled in this conference","Голосові запити відключені в цій конференції"}.
{"Voice request","Голосовий запит"}.
{"Web client which allows to join the room anonymously","Веб-клієнт, який дозволяє анонімно приєднатися до кімнати"}.
{"Wednesday","Середа"}.
{"When a new subscription is processed and whenever a subscriber comes online","Коли обробляється нова підписка та щоразу, коли абонент виходить в Інтернет"}.
{"When a new subscription is processed","Під час обробки нової підписки"}.
+17 -12
View File
@@ -4,10 +4,10 @@
%% https://docs.ejabberd.im/developer/extending-ejabberd/localization/
{" (Add * to the end of field to match substring)"," (在字段末尾添加 * 以匹配子字符串)"}.
{" has set the subject to: "," 已将题设置为: "}.
{" has set the subject to: "," 已将题设置为: "}.
{"# participants","# 参与者"}.
{"A description of the node","节点的描述"}.
{"A friendly name for the node","节点的易记名称"}.
{"A friendly name for the node","节点的友好名称"}.
{"A password is required to enter this room","需要密码才能进入此房间"}.
{"A Web Page","网页"}.
{"Accept","接受"}.
@@ -25,7 +25,7 @@
{"Allow subscription","允许订阅"}.
{"Allow this Jabber ID to subscribe to this pubsub node?","是否允许此 Jabber ID 订阅此 pubsub 节点?"}.
{"Allow this person to register with the room?","是否允许此用户在房间注册?"}.
{"Allow users to change the subject","允许用户更改题"}.
{"Allow users to change the subject","允许用户更改题"}.
{"Allow users to query other users","允许用户查询其他用户"}.
{"Allow users to send invites","允许用户发送邀请"}.
{"Allow users to send private messages","允许用户发送私信"}.
@@ -46,7 +46,9 @@
{"Anyone with a presence subscription of both or from may subscribe and retrieve items","任何拥有 both 或 from 的在线状态订阅的用户都可以订阅和检索项目"}.
{"Anyone with Voice","任何有发言权的人"}.
{"Anyone","任何人"}.
{"API Commands","API 命令"}.
{"April","四月"}.
{"Arguments","参数"}.
{"Attribute 'channel' is required for this request","此请求要求“channel”属性"}.
{"Attribute 'id' is mandatory for MIX messages","对于 MIX 消息,“id”属性是必需的"}.
{"Attribute 'jid' is not allowed here","此处不允许“jid”属性"}.
@@ -86,6 +88,7 @@
{"Choose whether to approve this entity's subscription.","选择是否批准此实体的订阅。"}.
{"City","城市"}.
{"Client acknowledged more stanzas than sent by server","客户端确认的节数多于服务器发送的节数"}.
{"Clustering","集群"}.
{"Commands","命令"}.
{"Conference room does not exist","会议室不存在"}.
{"Configuration of room ~s","房间 ~s 的配置"}.
@@ -227,12 +230,12 @@
{"Logged Out","已登出"}.
{"Logging","日志记录"}.
{"Make participants list public","公开参与者列表"}.
{"Make room CAPTCHA protected","启房间验证码保护"}.
{"Make room CAPTCHA protected","启房间验证码保护"}.
{"Make room members-only","将房间设为仅成员"}.
{"Make room moderated","启房间发言审核"}.
{"Make room password protected","启房间密码保护"}.
{"Make room moderated","启房间发言审核"}.
{"Make room password protected","启房间密码保护"}.
{"Make room persistent","将房间设为持久"}.
{"Make room public searchable","将房间设为公开搜索"}.
{"Make room public searchable","将房间设为公开搜索"}.
{"Malformed username","用户名格式不正确"}.
{"MAM preference modification denied by service policy","服务策略拒绝修改 MAM 首选项"}.
{"March","三月"}.
@@ -324,7 +327,7 @@
{"Number of seconds after which to automatically purge items, or `max` for no specific limit other than a server imposed maximum","自动清除项目前的秒数,`max` 表示除服务器强制规定的最大值外无其他特定限制"}.
{"Occupants are allowed to invite others","允许使用者邀请他人"}.
{"Occupants are allowed to query others","允许使用者查询他人"}.
{"Occupants May Change the Subject","使用者可以更改题"}.
{"Occupants May Change the Subject","使用者可以更改题"}.
{"October","十月"}.
{"OK","确定"}.
{"Old Password:","旧密码:"}.
@@ -335,8 +338,8 @@
{"Only <enable/> or <disable/> tags are allowed","仅允许 <enable/> 或 <disable/> 标签"}.
{"Only <list/> element is allowed in this query","此查询中只允许 <list/> 元素"}.
{"Only members may query archives of this room","只有成员才能查询此房间的归档"}.
{"Only moderators and participants are allowed to change the subject in this room","只允许主持人和参与者更改此房间的题"}.
{"Only moderators are allowed to change the subject in this room","只允许主持人更改此房间的题"}.
{"Only moderators and participants are allowed to change the subject in this room","只允许主持人和参与者更改此房间的题"}.
{"Only moderators are allowed to change the subject in this room","只允许主持人更改此房间的题"}.
{"Only moderators are allowed to retract messages","只允许主持人撤回消息"}.
{"Only moderators can approve voice requests","只有主持人可以批准发言权请求"}.
{"Only occupants are allowed to send messages to the conference","只允许使用者向会议发送消息"}.
@@ -408,6 +411,7 @@
{"Restore binary backup immediately:","立即恢复二进制备份:"}.
{"Restore plain text backup immediately:","立即恢复纯文本备份:"}.
{"Restore","恢复"}.
{"Result","结果"}.
{"Roles and Affiliations that May Retrieve Member List","可以检索成员列表的角色和从属关系"}.
{"Roles for which Presence is Broadcasted","广播在线状态的角色"}.
{"Roles that May Send Private Messages","可以发送私信的角色"}.
@@ -456,7 +460,7 @@
{"Store plain text backup:","存储纯文本备份:"}.
{"Stream management is already enabled","已启用流管理"}.
{"Stream management is not enabled","未启用流管理"}.
{"Subject","题"}.
{"Subject","题"}.
{"Submitted","已提交"}.
{"Subscriber Address","订阅者地址"}.
{"Subscribers may publish","订阅者可以发布"}.
@@ -506,7 +510,7 @@
{"The presence states for which an entity wants to receive notifications","实体要接收通知的在线状态"}.
{"The query is only allowed from local users","仅允许来自本地用户的查询"}.
{"The query must not contain <item/> elements","查询不能包含 <item/> 元素"}.
{"The room subject can be modified by participants","参与者可以修改房间题"}.
{"The room subject can be modified by participants","参与者可以修改房间题"}.
{"The semantic type information of data in the node, usually specified by the namespace of the payload (if any)","节点中数据的语义类型信息,通常由有效负载的命名空间指定(如果有)"}.
{"The sender of the last received message","最后收到的消息的发送者"}.
{"The stanza MUST contain only one <active/> element, one <default/> element, or one <list/> element","节必须仅包含一个 <active/> 元素、一个 <default/> 元素或一个 <list/> 元素"}.
@@ -584,6 +588,7 @@
{"Visitor","参观者"}.
{"Voice requests are disabled in this conference","此会议中禁用了发言权请求"}.
{"Voice request","发言权请求"}.
{"Web client which allows to join the room anonymously","允许匿名加入房间的 Web 客户端"}.
{"Wednesday","周三"}.
{"When a new subscription is processed and whenever a subscriber comes online","处理新订阅时和订阅者上线时"}.
{"When a new subscription is processed","处理新订阅时"}.
+15 -8
View File
@@ -305,14 +305,21 @@ beams(external) ->
end
end, ExtMods),
case application:get_env(ejabberd, external_beams) of
{ok, Path} ->
case lists:member(Path, code:get_path()) of
true -> ok;
false -> code:add_patha(Path)
end,
Beams = filelib:wildcard(filename:join(Path, "*\.beam")),
CustMods = [list_to_atom(filename:rootname(filename:basename(Beam)))
|| Beam <- Beams],
{ok, Path0} ->
Paths = case Path0 of
[L|_] = V when is_list(L) -> V;
L -> [L]
end,
CustMods = lists:foldl(
fun(Path, CM) ->
case lists:member(Path, code:get_path()) of
true -> ok;
false -> code:add_patha(Path)
end,
Beams = filelib:wildcard(filename:join(Path, "*\.beam")),
CM ++ [list_to_atom(filename:rootname(filename:basename(Beam)))
|| Beam <- Beams]
end, [], Paths),
CustMods ++ ExtMods;
_ ->
ExtMods
+18 -1
View File
@@ -63,6 +63,7 @@
kick_user/2,
kick_user/3,
kick_user_restuple/2,
kick_users/1,
get_session_pid/3,
get_session_sid/3,
get_session_sids/2,
@@ -1072,7 +1073,18 @@ get_commands_spec() ->
args_example = [<<"user1">>, <<"example.com">>],
result_desc = "The result text indicates the number of sessions that were kicked",
result_example = {ok, <<"Kicked sessions: 2">>},
result = {res, restuple}}].
result = {res, restuple}},
#ejabberd_commands{name = kick_users, tags = [session],
desc = "Disconnect all given host users' active sessions",
module = ?MODULE, function = kick_users,
note = "added in 25.04",
args = [{host, binary}],
args_desc = ["Server name"],
args_example = [<<"example.com">>],
result_desc = "Number of sessions that were kicked",
result_example = 3,
result = {num_sessions, integer}}].
-spec connected_users() -> [binary()].
@@ -1111,5 +1123,10 @@ kick_user_restuple(User, Server) ->
NumberBin = integer_to_binary(kick_user(User, Server)),
{ok, <<"Kicked sessions: ", NumberBin/binary>>}.
-spec kick_users(binary()) -> non_neg_integer().
kick_users(Server) ->
length([kick_user(U, S, R) || {U, S, R} <-get_vh_session_list(Server)]).
make_sid() ->
{misc:unique_timestamp(), self()}.
+7 -4
View File
@@ -410,18 +410,21 @@ sqlite_table_copy_t(SchemaInfo, Table) ->
NewTableName = <<"new_", TableName/binary>>,
NewTable = Table#sql_table{name = NewTableName},
create_table_t(SchemaInfo, NewTable),
SQL2 = <<"INSERT INTO ", NewTableName/binary,
" SELECT * FROM ", TableName/binary>>,
Columns = lists:join(<<",">>,
lists:map(fun(C) -> escape_name(SchemaInfo, C#sql_column.name) end,
Table#sql_table.columns)),
SQL2 = [<<"INSERT INTO ">>, NewTableName,
<<" SELECT ">>, Columns, <<" FROM ">>, TableName],
?INFO_MSG("Copying table ~s to ~s:~n~s~n",
[TableName, NewTableName, SQL2]),
ejabberd_sql:sql_query_t(SQL2),
SQL3 = <<"DROP TABLE ", TableName/binary>>,
?INFO_MSG("Droping old table ~s:~n~s~n",
[TableName, SQL2]),
[TableName, SQL3]),
ejabberd_sql:sql_query_t(SQL3),
SQL4 = <<"ALTER TABLE ", NewTableName/binary,
" RENAME TO ", TableName/binary>>,
?INFO_MSG("Renameing table ~s to ~s:~n~s~n",
?INFO_MSG("Renaming table ~s to ~s:~n~s~n",
[NewTableName, TableName, SQL4]),
ejabberd_sql:sql_query_t(SQL4).
+7 -2
View File
@@ -584,12 +584,17 @@ process_admin(Host, #request{path = [<<"users">> | RPath], lang = Lang} = R, AJI
process_admin(Host, #request{path = [<<"online-users">> | RPath], lang = Lang} = R, AJID)
when is_binary(Host) ->
Level = 3 + length(RPath),
Res = [make_command(connected_users_vhost,
Set = [make_command(kick_users,
R,
[{<<"host">>, Host}],
[{style, danger}, {force_execution, false}])],
timer:sleep(200), % small delay after kicking users before getting the updated list
Get = [make_command(connected_users_vhost,
R,
[{<<"host">>, Host}],
[{table_options, {100, RPath}},
{result_links, [{sessions, user, Level, <<"">>}]}])],
make_xhtml([?XCT(<<"h1">>, ?T("Online Users"))] ++ Res, Host, R, AJID, Level);
make_xhtml([?XCT(<<"h1">>, ?T("Online Users"))] ++ Set ++ Get, Host, R, AJID, Level);
process_admin(Host,
#request{path = [<<"last-activity">>],
q = Query,
+8 -4
View File
@@ -1899,16 +1899,20 @@ srg_create2(Group, Host, Label, Description, DisplayList) ->
Opts = [{label, Label},
{displayed_groups, DisplayList},
{description, Description}],
{atomic, _} = mod_shared_roster:create_group(Host, Group, Opts),
ok.
case mod_shared_roster:create_group(Host, Group, Opts) of
{atomic, _} -> ok;
{error, Err} -> Err
end.
srg_add(Group, Host) ->
Opts = [{label, <<"">>},
{description, <<"">>},
{displayed_groups, []}
],
{atomic, _} = mod_shared_roster:create_group(Host, Group, Opts),
ok.
case mod_shared_roster:create_group(Host, Group, Opts) of
{atomic, _} -> ok;
{error, Err} -> Err
end.
srg_delete(Group, Host) ->
{atomic, _} = mod_shared_roster:delete_group(Host, Group),
+1 -1
View File
@@ -71,7 +71,7 @@ add_occupantid_packet(Packet, RoomJid) ->
From = xmpp:get_from(Packet),
OccupantId = calculate_occupantid(From, RoomJid),
OccupantElement = #occupant_id{id = OccupantId},
xmpp:set_subtag(Packet, OccupantElement).
xmpp:append_subtags(xmpp:remove_subtag(Packet, OccupantElement), [OccupantElement]).
calculate_occupantid(From, RoomJid) ->
Term = {jid:remove_resource(From), get_salt(RoomJid)},
+1 -1
View File
@@ -381,7 +381,7 @@ create_group(Host, Group) ->
create_group(Host, Group, []).
create_group(Host, Group, Opts) ->
case jid:nodeprep(Group) of
case jid:nameprep(Group) of
error ->
{error, invalid_group_name};
LGroup ->
@@ -14,6 +14,7 @@ define_macro:
mod_muc:
db_type: internal
vcard: VCARD
mod_muc_occupantid: []
mod_offline:
db_type: internal
mod_privacy:
@@ -22,6 +22,7 @@ define_macro:
db_type: sql
ram_db_type: sql
vcard: VCARD
mod_muc_occupantid: []
mod_offline:
use_cache: true
db_type: sql
@@ -22,6 +22,7 @@ define_macro:
db_type: sql
ram_db_type: sql
vcard: VCARD
mod_muc_occupantid: []
mod_offline:
use_cache: true
db_type: sql
@@ -22,6 +22,7 @@ define_macro:
db_type: sql
ram_db_type: sql
vcard: VCARD
mod_muc_occupantid: []
mod_offline:
use_cache: true
db_type: sql
@@ -15,6 +15,7 @@ define_macro:
mod_muc:
db_type: internal
vcard: VCARD
mod_muc_occupantid: []
mod_offline:
db_type: internal
mod_privacy:
@@ -1,5 +1,8 @@
define_macro:
SQLITE_CONFIG:
auth_stored_password_types:
- plain
- scram_sha256
sql_type: sqlite
sql_pool_size: 1
auth_method: sql
@@ -17,6 +20,7 @@ define_macro:
db_type: sql
ram_db_type: sql
vcard: VCARD
mod_muc_occupantid: []
mod_offline:
db_type: sql
mod_privacy:
+1
View File
@@ -123,6 +123,7 @@ modules:
vcard: VCARD
mod_muc:
vcard: VCARD
mod_muc_occupantid: []
mod_muc_admin: []
mod_carboncopy: []
mod_jidprep: []
+69 -4
View File
@@ -304,7 +304,70 @@ master_slave_cases() ->
master_slave_test(config_allow_voice_requests),
master_slave_test(config_voice_request_interval),
master_slave_test(config_visitor_nickchange),
master_slave_test(join_conflict)]}.
master_slave_test(join_conflict),
master_slave_test(duplicate_occupantid)
]}.
duplicate_occupantid_master(Config) ->
Room = muc_room_jid(Config),
PeerJID = ?config(slave, Config),
PeerNick = ?config(slave_nick, Config),
PeerNickJID = jid:replace_resource(Room, PeerNick),
MyNick = ?config(nick, Config),
MyNickJID = jid:replace_resource(Room, MyNick),
ok = join_new(Config),
wait_for_slave(Config),
Pres = ?match(#presence{from = PeerNickJID, type = available} = Pres,
recv_presence(Config), Pres),
?match(#muc_user{items = [#muc_item{jid = PeerJID,
role = participant,
affiliation = none}]},
xmpp:get_subtag(Pres, #muc_user{})),
OccupantId = ?match([#occupant_id{id = Id}], xmpp:get_subtags(Pres, #occupant_id{}), Id),
Pres2 = ?match(#presence{from = PeerNickJID, type = available} = Pres2,
recv_presence(Config), Pres2),
?match([#occupant_id{id = OccupantId}], xmpp:get_subtags(Pres2, #occupant_id{})),
Body = xmpp:mk_text(<<"test-1">>),
Msg = ?match(#message{type = groupchat, from = PeerNickJID,
body = Body} = Msg, recv_message(Config), Msg),
?match([#occupant_id{id = OccupantId}], xmpp:get_subtags(Msg, #occupant_id{})),
recv_muc_presence(Config, PeerNickJID, unavailable),
ok = leave(Config),
disconnect(Config).
duplicate_occupantid_slave(Config) ->
Room = muc_room_jid(Config),
MyNick = ?config(slave_nick, Config),
MyNickJID = jid:replace_resource(Room, MyNick),
PeerNick = ?config(master_nick, Config),
PeerNickJID = jid:replace_resource(Room, PeerNick),
wait_for_master(Config),
send(Config, #presence{to = MyNickJID, sub_els = [#muc{}]}),
?match(#presence{from = Room, type = available}, recv_presence(Config)),
OccupantId = case recv_presence(Config) of
#presence{from = MyNickJID, type = available} = Pres ->
recv_muc_presence(Config, PeerNickJID, available),
?match([#occupant_id{id = Id}], xmpp:get_subtags(Pres, #occupant_id{}), Id);
#presence{from = PeerNickJID, type = available} ->
Pres2 = ?match(#presence{from = MyNickJID, type = available} = Pres2,
recv_presence(Config), Pres2),
?match([#occupant_id{id = Id}], xmpp:get_subtags(Pres2, #occupant_id{}), Id)
end,
?match(#message{type = groupchat, from = Room}, recv_message(Config)),
send(Config, #presence{to = Room, sub_els = [#occupant_id{id = <<"fake1">>},
#occupant_id{id = <<"fake2">>}]}),
Pres3 = ?match(#presence{from = MyNickJID, type = available} = Pres3,
recv_presence(Config), Pres3),
?match([#occupant_id{id = OccupantId}], xmpp:get_subtags(Pres3, #occupant_id{})),
Body = xmpp:mk_text(<<"test-1">>),
send(Config, #message{to = Room, type = groupchat, body = Body,
sub_els = [#occupant_id{id = <<"fake1">>},
#occupant_id{id = <<"fake2">>}]}),
Msg = ?match(#message{type = groupchat, from = MyNickJID,
body = Body} = Msg, recv_message(Config), Msg),
?match([#occupant_id{id = OccupantId}], xmpp:get_subtags(Msg, #occupant_id{})),
ok = leave(Config),
disconnect(Config).
join_conflict_master(Config) ->
ok = join_new(Config),
@@ -1628,7 +1691,7 @@ join(Config, Role, Aff) when is_atom(Role), is_atom(Aff) ->
join(Config, Role, #muc{} = SubEl) when is_atom(Role) ->
join(Config, Role, none, SubEl).
join(Config, Role, Aff, SubEl) ->
join(Config, Role, Aff, SubEls) when is_list(SubEls) ->
ct:comment("Joining existing room as ~s/~s", [Aff, Role]),
MyJID = my_jid(Config),
Room = muc_room_jid(Config),
@@ -1636,7 +1699,7 @@ join(Config, Role, Aff, SubEl) ->
MyNickJID = jid:replace_resource(Room, MyNick),
PeerNick = ?config(peer_nick, Config),
PeerNickJID = jid:replace_resource(Room, PeerNick),
send(Config, #presence{to = MyNickJID, sub_els = [SubEl]}),
send(Config, #presence{to = MyNickJID, sub_els = SubEls}),
case recv_presence(Config) of
#presence{type = error, from = MyNickJID} = Err ->
xmpp:get_subtag(Err, #stanza_error{});
@@ -1667,7 +1730,9 @@ join(Config, Role, Aff, SubEl) ->
{History, Subj} = recv_history_and_subject(Config),
{empty, History, Subj, Codes}
end
end.
end;
join(Config, Role, Aff, SubEl) ->
join(Config, Role, Aff, [SubEl]).
leave(Config) ->
leave(Config, muc_room_jid(Config)).
+1 -1
View File
@@ -71,7 +71,7 @@ expat_vsn='2.6.4'
zlib_vsn='1.3.1'
yaml_vsn='0.2.5'
ssl_vsn='3.4.1'
otp_vsn='27.3'
otp_vsn='27.3.2'
elixir_vsn='1.18.3'
pam_vsn='1.6.1' # Newer Linux-PAM versions use Meson, we don't support that yet.
png_vsn='1.6.45'