Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ef754939c4 | |||
| ee3a0b8b1a | |||
| 2182cb60ae | |||
| 4da8278e66 | |||
| 629db496b5 | |||
| f79b8e166a | |||
| fae4ab97fd | |||
| da8d04a654 | |||
| ce02fc485f | |||
| 69695ffe27 | |||
| 6fdb467484 | |||
| d8016a6477 | |||
| e43d864184 | |||
| 4d3681aba1 | |||
| d791f6ceaa | |||
| 602a42f5ce | |||
| c98739d5b5 | |||
| 425504454c | |||
| 780031847c | |||
| c3af613db1 | |||
| babd01a87f | |||
| 17b605a32b | |||
| fc813acd7b | |||
| d842d6772d | |||
| 67aaf93157 | |||
| 9154275431 | |||
| c343ef7aad | |||
| 78093735b7 | |||
| ed6a111982 | |||
| a8a5be7a34 | |||
| 5008947e32 | |||
| 0827a5116f |
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;"
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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)"
|
||||
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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ó"}.
|
||||
|
||||
@@ -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
@@ -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"}.
|
||||
|
||||
@@ -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"}.
|
||||
|
||||
@@ -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"}.
|
||||
|
||||
@@ -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' s’lejohet këtu"}.
|
||||
{"Attribute 'node' is not allowed here","Atributi 'node' s’lejohet këtu"}.
|
||||
|
||||
@@ -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"}.
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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()}.
|
||||
|
||||
@@ -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).
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)},
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -123,6 +123,7 @@ modules:
|
||||
vcard: VCARD
|
||||
mod_muc:
|
||||
vcard: VCARD
|
||||
mod_muc_occupantid: []
|
||||
mod_muc_admin: []
|
||||
mod_carboncopy: []
|
||||
mod_jidprep: []
|
||||
|
||||
+69
-4
@@ -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
@@ -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'
|
||||
|
||||
Reference in New Issue
Block a user