-
-
-
-
- {% if containers["solr-mailcow"].State.Running == 1 %}
-
-
-
-

-
-
- {% if solr_status != false %}
-
-
{{ lang.debug.jvm_memory_solr }}: {{ (solr_status.jvm.memory.total - solr_status.jvm.memory.free) }} / {{ solr_status.jvm.memory.total }}
- ({{ solr_status.jvm.memory.raw['used%']|round }}%)
-
-
{{ lang.debug.uptime }}: {{ solr_uptime }}h
-
{{ lang.debug.started_at }}: {{ solr_status.status['dovecot-fts'].startTime }}
-
{{ lang.debug.last_modified }}: {{ solr_status.status['dovecot-fts'].index.lastModified }}
-
{{ lang.debug.size }}: {{ solr_status.status['dovecot-fts'].index.size }}
-
{{ lang.debug.docs }}: {{ solr_status.status['dovecot-fts'].index.numDocs }}
- {% else %}
-
{{ lang.debug.solr_dead }}
- {% endif %}
-
-
-
Disk I/O
-
- Loading...
-
-
-
-
-
Net I/O
-
- Loading...
-
-
-
-
-
-
- {% endif %}
-
-
-
{% for container, container_info in containers %}
- {% if container != "solr-mailcow" %}
- {% endif %}
{% endfor %}
diff --git a/docker-compose.yml b/docker-compose.yml
index f815ab9b4..55481fb50 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -165,7 +165,7 @@ services:
- API_KEY_READ_ONLY=${API_KEY_READ_ONLY:-invalid}
- API_ALLOW_FROM=${API_ALLOW_FROM:-invalid}
- COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized}
- - SKIP_SOLR=${SKIP_SOLR:-y}
+ - SKIP_FTS=${SKIP_FTS:-y}
- SKIP_CLAMD=${SKIP_CLAMD:-n}
- SKIP_SOGO=${SKIP_SOGO:-n}
- ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
@@ -174,7 +174,6 @@ services:
- DEMO_MODE=${DEMO_MODE:-n}
- WEBAUTHN_ONLY_TRUSTED_VENDORS=${WEBAUTHN_ONLY_TRUSTED_VENDORS:-n}
- CLUSTERMODE=${CLUSTERMODE:-}
- - FLATCURVE_EXPERIMENTAL=${FLATCURVE_EXPERIMENTAL:-}
restart: always
networks:
mailcow-network:
@@ -234,6 +233,7 @@ services:
depends_on:
- mysql-mailcow
- netfilter-mailcow
+ - redis-mailcow
dns:
- ${IPV4_NETWORK:-172.22.1}.254
cap_add:
@@ -267,14 +267,15 @@ services:
- ALLOW_ADMIN_EMAIL_LOGIN=${ALLOW_ADMIN_EMAIL_LOGIN:-n}
- MAILDIR_GC_TIME=${MAILDIR_GC_TIME:-7200}
- ACL_ANYONE=${ACL_ANYONE:-disallow}
- - SKIP_SOLR=${SKIP_SOLR:-y}
+ - SKIP_FTS=${SKIP_FTS:-y}
+ - FTS_HEAP=${FTS_HEAP:-512}
+ - FTS_PROCS=${FTS_PROCS:-3}
- MAILDIR_SUB=${MAILDIR_SUB:-}
- MASTER=${MASTER:-y}
- REDIS_SLAVEOF_IP=${REDIS_SLAVEOF_IP:-}
- REDIS_SLAVEOF_PORT=${REDIS_SLAVEOF_PORT:-}
- REDISPASS=${REDISPASS}
- COMPOSE_PROJECT_NAME=${COMPOSE_PROJECT_NAME:-mailcow-dockerized}
- - FLATCURVE_EXPERIMENTAL=${FLATCURVE_EXPERIMENTAL:-n}
ports:
- "${DOVEADM_PORT:-127.0.0.1:19991}:12345"
- "${IMAP_PORT:-143}:143"
@@ -558,28 +559,6 @@ services:
aliases:
- dockerapi
-
- ##### Will be removed soon #####
- solr-mailcow:
- image: mailcow/solr:1.8.3
- restart: always
- depends_on:
- - netfilter-mailcow
- volumes:
- - solr-vol-1:/opt/solr/server/solr/dovecot-fts/data
- ports:
- - "${SOLR_PORT:-127.0.0.1:18983}:8983"
- environment:
- - TZ=${TZ}
- - SOLR_HEAP=${SOLR_HEAP:-1024}
- - SKIP_SOLR=${SKIP_SOLR:-y}
- - FLATCURVE_EXPERIMENTAL=${FLATCURVE_EXPERIMENTAL:-n}
- networks:
- mailcow-network:
- aliases:
- - solr
- ################################
-
olefy-mailcow:
image: mailcow/olefy:1.13
restart: always
@@ -636,7 +615,6 @@ services:
- netfilter-mailcow
- watchdog-mailcow
- dockerapi-mailcow
- - solr-mailcow
environment:
- TZ=${TZ}
image: robbertkl/ipv6nat
@@ -668,7 +646,6 @@ volumes:
mysql-socket-vol-1:
redis-vol-1:
rspamd-vol-1:
- solr-vol-1:
postfix-vol-1:
crypt-vol-1:
sogo-web-vol-1:
diff --git a/generate_config.sh b/generate_config.sh
index 915a5d907..6e66c9197 100755
--- a/generate_config.sh
+++ b/generate_config.sh
@@ -175,28 +175,6 @@ if [ -z "${SKIP_CLAMD}" ]; then
fi
fi
-if [ -z "${SKIP_SOLR}" ]; then
- if [ "${MEM_TOTAL}" -le "2097152" ]; then
- echo "Disabling Solr on low-memory system."
- SKIP_SOLR=y
- elif [ "${MEM_TOTAL}" -le "3670016" ]; then
- echo "Installed memory is <= 3.5 GiB. It is recommended to disable Solr to prevent out-of-memory situations."
- echo "Solr is a prone to run OOM and should be monitored. The default Solr heap size is 1024 MiB and should be set in mailcow.conf according to your expected load."
- echo "Solr can be re-enabled by setting SKIP_SOLR=n in mailcow.conf but will refuse to start with less than 2 GB total memory."
- read -r -p "Do you want to disable Solr now? [Y/n] " response
- case $response in
- [nN][oO]|[nN])
- SKIP_SOLR=n
- ;;
- *)
- SKIP_SOLR=y
- ;;
- esac
- else
- SKIP_SOLR=n
- fi
-fi
-
if [[ ${SKIP_BRANCH} != y ]]; then
echo "Which branch of mailcow do you want to use?"
echo ""
@@ -305,7 +283,6 @@ POPS_PORT=995
SIEVE_PORT=4190
DOVEADM_PORT=127.0.0.1:19991
SQL_PORT=127.0.0.1:13306
-SOLR_PORT=127.0.0.1:18983
REDIS_PORT=127.0.0.1:7654
# Your timezone
@@ -402,14 +379,22 @@ SKIP_CLAMD=${SKIP_CLAMD}
SKIP_SOGO=n
-# Skip Solr on low-memory systems or if you do not want to store a readable index of your mails in solr-vol-1.
+# Skip FTS (Fulltext Search) for Dovecot on low-memory systems or if you simply want to disable it.
+# Dovecot inside mailcow use Flatcurve as FTS Backend.
-SKIP_SOLR=${SKIP_SOLR}
+SKIP_FTS=n
-# Solr heap size in MB, there is no recommendation, please see Solr docs.
-# Solr is a prone to run OOM and should be monitored. Unmonitored Solr setups are not recommended.
+# Dovecot Indexing (FTS) Process maximum heap size in MB, there is no recommendation, please see Dovecot docs.
+# Flatcurve (Xapian backend) is used as the FTS Indexer. It is supposed to be efficient in CPU and RAM consumption.
+# However: Please always monitor your Resource consumption!
-SOLR_HEAP=1024
+FTS_HEAP=128
+
+# Controls how many processes the Dovecot indexing process can spawn at max.
+# Too many indexing processes can use a lot of CPU and Disk I/O.
+# Please visit: https://doc.dovecot.org/configuration_manual/service_configuration/#indexer-worker for more informations
+
+FTS_PROCS=5
# Allow admins to log into SOGo as email user (without any password)
diff --git a/helper-scripts/docker-compose.override.yml.d/BUILD_FLAGS/docker-compose.override.yml b/helper-scripts/docker-compose.override.yml.d/BUILD_FLAGS/docker-compose.override.yml
index d2dd0f606..00128de37 100644
--- a/helper-scripts/docker-compose.override.yml.d/BUILD_FLAGS/docker-compose.override.yml
+++ b/helper-scripts/docker-compose.override.yml.d/BUILD_FLAGS/docker-compose.override.yml
@@ -34,8 +34,5 @@ services:
dockerapi-mailcow:
build: ./data/Dockerfiles/dockerapi
- solr-mailcow:
- build: ./data/Dockerfiles/solr
-
olefy-mailcow:
build: ./data/Dockerfiles/olefy
diff --git a/update.sh b/update.sh
index 8ed414d03..d488c4784 100755
--- a/update.sh
+++ b/update.sh
@@ -303,6 +303,400 @@ fix_broken_dnslist_conf() {
}
+adapt_new_options() {
+
+ CONFIG_ARRAY=(
+ "SKIP_LETS_ENCRYPT"
+ "SKIP_SOGO"
+ "USE_WATCHDOG"
+ "WATCHDOG_NOTIFY_EMAIL"
+ "WATCHDOG_NOTIFY_WEBHOOK"
+ "WATCHDOG_NOTIFY_WEBHOOK_BODY"
+ "WATCHDOG_NOTIFY_BAN"
+ "WATCHDOG_NOTIFY_START"
+ "WATCHDOG_EXTERNAL_CHECKS"
+ "WATCHDOG_SUBJECT"
+ "SKIP_CLAMD"
+ "SKIP_IP_CHECK"
+ "ADDITIONAL_SAN"
+ "DOVEADM_PORT"
+ "IPV4_NETWORK"
+ "IPV6_NETWORK"
+ "LOG_LINES"
+ "SNAT_TO_SOURCE"
+ "SNAT6_TO_SOURCE"
+ "COMPOSE_PROJECT_NAME"
+ "DOCKER_COMPOSE_VERSION"
+ "SQL_PORT"
+ "API_KEY"
+ "API_KEY_READ_ONLY"
+ "API_ALLOW_FROM"
+ "MAILDIR_GC_TIME"
+ "MAILDIR_SUB"
+ "ACL_ANYONE"
+ "FTS_HEAP"
+ "FTS_PROCS"
+ "SKIP_FTS"
+ "ENABLE_SSL_SNI"
+ "ALLOW_ADMIN_EMAIL_LOGIN"
+ "SKIP_HTTP_VERIFICATION"
+ "SOGO_EXPIRE_SESSION"
+ "REDIS_PORT"
+ "DOVECOT_MASTER_USER"
+ "DOVECOT_MASTER_PASS"
+ "MAILCOW_PASS_SCHEME"
+ "ADDITIONAL_SERVER_NAMES"
+ "ACME_CONTACT"
+ "WATCHDOG_VERBOSE"
+ "WEBAUTHN_ONLY_TRUSTED_VENDORS"
+ "SPAMHAUS_DQS_KEY"
+ "SKIP_UNBOUND_HEALTHCHECK"
+ "DISABLE_NETFILTER_ISOLATION_RULE"
+ )
+
+ sed -i --follow-symlinks '$a\' mailcow.conf
+ for option in ${CONFIG_ARRAY[@]}; do
+ if [[ ${option} == "ADDITIONAL_SAN" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo "${option}=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "COMPOSE_PROJECT_NAME" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo "COMPOSE_PROJECT_NAME=mailcowdockerized" >> mailcow.conf
+ fi
+ elif [[ ${option} == "DOCKER_COMPOSE_VERSION" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo "# Used Docker Compose version" >> mailcow.conf
+ echo "# Switch here between native (compose plugin) and standalone" >> mailcow.conf
+ echo "# For more informations take a look at the mailcow docs regarding the configuration options." >> mailcow.conf
+ echo "# Normally this should be untouched but if you decided to use either of those you can switch it manually here." >> mailcow.conf
+ echo "# Please be aware that at least one of those variants should be installed on your maschine or mailcow will fail." >> mailcow.conf
+ echo "" >> mailcow.conf
+ echo "DOCKER_COMPOSE_VERSION=${DOCKER_COMPOSE_VERSION}" >> mailcow.conf
+ fi
+ elif [[ ${option} == "DOVEADM_PORT" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo "DOVEADM_PORT=127.0.0.1:19991" >> mailcow.conf
+ fi
+ elif [[ ${option} == "WATCHDOG_NOTIFY_EMAIL" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo "WATCHDOG_NOTIFY_EMAIL=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "LOG_LINES" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Max log lines per service to keep in Redis logs' >> mailcow.conf
+ echo "LOG_LINES=9999" >> mailcow.conf
+ fi
+ elif [[ ${option} == "IPV4_NETWORK" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Internal IPv4 /24 subnet, format n.n.n. (expands to n.n.n.0/24)' >> mailcow.conf
+ echo "IPV4_NETWORK=172.22.1" >> mailcow.conf
+ fi
+ elif [[ ${option} == "IPV6_NETWORK" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Internal IPv6 subnet in fc00::/7' >> mailcow.conf
+ echo "IPV6_NETWORK=fd4d:6169:6c63:6f77::/64" >> mailcow.conf
+ fi
+ elif [[ ${option} == "SQL_PORT" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Bind SQL to 127.0.0.1 on port 13306' >> mailcow.conf
+ echo "SQL_PORT=127.0.0.1:13306" >> mailcow.conf
+ fi
+ elif [[ ${option} == "API_KEY" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Create or override API key for web UI' >> mailcow.conf
+ echo "#API_KEY=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "API_KEY_READ_ONLY" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Create or override read-only API key for web UI' >> mailcow.conf
+ echo "#API_KEY_READ_ONLY=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "API_ALLOW_FROM" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Must be set for API_KEY to be active' >> mailcow.conf
+ echo '# IPs only, no networks (networks can be set via UI)' >> mailcow.conf
+ echo "#API_ALLOW_FROM=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "SNAT_TO_SOURCE" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Use this IPv4 for outgoing connections (SNAT)' >> mailcow.conf
+ echo "#SNAT_TO_SOURCE=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "SNAT6_TO_SOURCE" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Use this IPv6 for outgoing connections (SNAT)' >> mailcow.conf
+ echo "#SNAT6_TO_SOURCE=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "MAILDIR_GC_TIME" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Garbage collector cleanup' >> mailcow.conf
+ echo '# Deleted domains and mailboxes are moved to /var/vmail/_garbage/timestamp_sanitizedstring' >> mailcow.conf
+ echo '# How long should objects remain in the garbage until they are being deleted? (value in minutes)' >> mailcow.conf
+ echo '# Check interval is hourly' >> mailcow.conf
+ echo 'MAILDIR_GC_TIME=1440' >> mailcow.conf
+ fi
+ elif [[ ${option} == "ACL_ANYONE" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Set this to "allow" to enable the anyone pseudo user. Disabled by default.' >> mailcow.conf
+ echo '# When enabled, ACL can be created, that apply to "All authenticated users"' >> mailcow.conf
+ echo '# This should probably only be activated on mail hosts, that are used exclusivly by one organisation.' >> mailcow.conf
+ echo '# Otherwise a user might share data with too many other users.' >> mailcow.conf
+ echo 'ACL_ANYONE=disallow' >> mailcow.conf
+ fi
+ elif [[ ${option} == "FTS_HEAP" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Dovecot Indexing (FTS) Process maximum heap size in MB, there is no recommendation, please see Dovecot docs.' >> mailcow.conf
+ echo '# Flatcurve is used as FTS Engine. It is supposed to be pretty efficient in CPU and RAM consumption.' >> mailcow.conf
+ echo '# Please always monitor your Resource consumption!' >> mailcow.conf
+ echo "FTS_HEAP=1024" >> mailcow.conf
+ fi
+ elif [[ ${option} == "SKIP_FTS" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Skip FTS (Fulltext Search) for Dovecot on low-memory systems or if you simply want to disable it.' >> mailcow.conf
+ echo "# Dovecot inside mailcow use Flatcurve as FTS Backend." >> mailcow.conf
+ echo "SKIP_FTS=n" >> mailcow.conf
+ fi
+ elif [[ ${option} == "FTS_PROCS" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Controls how many processes the Dovecot indexing process can spawn at max.' >> mailcow.conf
+ echo '# Too many indexing processes can use a lot of CPU and Disk I/O' >> mailcow.conf
+ echo '# Please visit: https://doc.dovecot.org/configuration_manual/service_configuration/#indexer-worker for more informations' >> mailcow.conf
+ echo "FTS_PROCS=2" >> mailcow.conf
+ fi
+ elif [[ ${option} == "ENABLE_SSL_SNI" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Create seperate certificates for all domains - y/n' >> mailcow.conf
+ echo '# this will allow adding more than 100 domains, but some email clients will not be able to connect with alternative hostnames' >> mailcow.conf
+ echo '# see https://wiki.dovecot.org/SSL/SNIClientSupport' >> mailcow.conf
+ echo "ENABLE_SSL_SNI=n" >> mailcow.conf
+ fi
+ elif [[ ${option} == "SKIP_SOGO" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Skip SOGo: Will disable SOGo integration and therefore webmail, DAV protocols and ActiveSync support (experimental, unsupported, not fully implemented) - y/n' >> mailcow.conf
+ echo "SKIP_SOGO=n" >> mailcow.conf
+ fi
+ elif [[ ${option} == "MAILDIR_SUB" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# MAILDIR_SUB defines a path in a users virtual home to keep the maildir in. Leave empty for updated setups.' >> mailcow.conf
+ echo "#MAILDIR_SUB=Maildir" >> mailcow.conf
+ echo "MAILDIR_SUB=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "WATCHDOG_NOTIFY_WEBHOOK" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Send notifications to a webhook URL that receives a POST request with the content type "application/json".' >> mailcow.conf
+ echo '# You can use this to send notifications to services like Discord, Slack and others.' >> mailcow.conf
+ echo '#WATCHDOG_NOTIFY_WEBHOOK=https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' >> mailcow.conf
+ fi
+ elif [[ ${option} == "WATCHDOG_NOTIFY_WEBHOOK_BODY" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# JSON body included in the webhook POST request. Needs to be in single quotes.' >> mailcow.conf
+ echo '# Following variables are available: SUBJECT, BODY' >> mailcow.conf
+ WEBHOOK_BODY='{"username": "mailcow Watchdog", "content": "**${SUBJECT}**\n${BODY}"}'
+ echo "#WATCHDOG_NOTIFY_WEBHOOK_BODY='${WEBHOOK_BODY}'" >> mailcow.conf
+ fi
+ elif [[ ${option} == "WATCHDOG_NOTIFY_BAN" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Notify about banned IP. Includes whois lookup.' >> mailcow.conf
+ echo "WATCHDOG_NOTIFY_BAN=y" >> mailcow.conf
+ fi
+ elif [[ ${option} == "WATCHDOG_NOTIFY_START" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Send a notification when the watchdog is started.' >> mailcow.conf
+ echo "WATCHDOG_NOTIFY_START=y" >> mailcow.conf
+ fi
+ elif [[ ${option} == "WATCHDOG_SUBJECT" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Subject for watchdog mails. Defaults to "Watchdog ALERT" followed by the error message.' >> mailcow.conf
+ echo "#WATCHDOG_SUBJECT=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "WATCHDOG_EXTERNAL_CHECKS" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Checks if mailcow is an open relay. Requires a SAL. More checks will follow.' >> mailcow.conf
+ echo '# No data is collected. Opt-in and anonymous.' >> mailcow.conf
+ echo '# Will only work with unmodified mailcow setups.' >> mailcow.conf
+ echo "WATCHDOG_EXTERNAL_CHECKS=n" >> mailcow.conf
+ fi
+ elif [[ ${option} == "SOGO_EXPIRE_SESSION" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# SOGo session timeout in minutes' >> mailcow.conf
+ echo "SOGO_EXPIRE_SESSION=480" >> mailcow.conf
+ fi
+ elif [[ ${option} == "REDIS_PORT" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo "REDIS_PORT=127.0.0.1:7654" >> mailcow.conf
+ fi
+ elif [[ ${option} == "DOVECOT_MASTER_USER" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# DOVECOT_MASTER_USER and _PASS must _both_ be provided. No special chars.' >> mailcow.conf
+ echo '# Empty by default to auto-generate master user and password on start.' >> mailcow.conf
+ echo '# User expands to DOVECOT_MASTER_USER@mailcow.local' >> mailcow.conf
+ echo '# LEAVE EMPTY IF UNSURE' >> mailcow.conf
+ echo "DOVECOT_MASTER_USER=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "DOVECOT_MASTER_PASS" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# LEAVE EMPTY IF UNSURE' >> mailcow.conf
+ echo "DOVECOT_MASTER_PASS=" >> mailcow.conf
+ fi
+ elif [[ ${option} == "MAILCOW_PASS_SCHEME" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Password hash algorithm' >> mailcow.conf
+ echo '# Only certain password hash algorithm are supported. For a fully list of supported schemes,' >> mailcow.conf
+ echo '# see https://docs.mailcow.email/models/model-passwd/' >> mailcow.conf
+ echo "MAILCOW_PASS_SCHEME=BLF-CRYPT" >> mailcow.conf
+ fi
+ elif [[ ${option} == "ADDITIONAL_SERVER_NAMES" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Additional server names for mailcow UI' >> mailcow.conf
+ echo '#' >> mailcow.conf
+ echo '# Specify alternative addresses for the mailcow UI to respond to' >> mailcow.conf
+ echo '# This is useful when you set mail.* as ADDITIONAL_SAN and want to make sure mail.maildomain.com will always point to the mailcow UI.' >> mailcow.conf
+ echo '# If the server name does not match a known site, Nginx decides by best-guess and may redirect users to the wrong web root.' >> mailcow.conf
+ echo '# You can understand this as server_name directive in Nginx.' >> mailcow.conf
+ echo '# Comma separated list without spaces! Example: ADDITIONAL_SERVER_NAMES=a.b.c,d.e.f' >> mailcow.conf
+ echo 'ADDITIONAL_SERVER_NAMES=' >> mailcow.conf
+ fi
+ elif [[ ${option} == "ACME_CONTACT" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Lets Encrypt registration contact information' >> mailcow.conf
+ echo '# Optional: Leave empty for none' >> mailcow.conf
+ echo '# This value is only used on first order!' >> mailcow.conf
+ echo '# Setting it at a later point will require the following steps:' >> mailcow.conf
+ echo '# https://docs.mailcow.email/troubleshooting/debug-reset_tls/' >> mailcow.conf
+ echo 'ACME_CONTACT=' >> mailcow.conf
+ fi
+ elif [[ ${option} == "WEBAUTHN_ONLY_TRUSTED_VENDORS" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo "# WebAuthn device manufacturer verification" >> mailcow.conf
+ echo '# After setting WEBAUTHN_ONLY_TRUSTED_VENDORS=y only devices from trusted manufacturers are allowed' >> mailcow.conf
+ echo '# root certificates can be placed for validation under mailcow-dockerized/data/web/inc/lib/WebAuthn/rootCertificates' >> mailcow.conf
+ echo 'WEBAUTHN_ONLY_TRUSTED_VENDORS=n' >> mailcow.conf
+ fi
+ elif [[ ${option} == "SPAMHAUS_DQS_KEY" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo "# Spamhaus Data Query Service Key" >> mailcow.conf
+ echo '# Optional: Leave empty for none' >> mailcow.conf
+ echo '# Enter your key here if you are using a blocked ASN (OVH, AWS, Cloudflare e.g) for the unregistered Spamhaus Blocklist.' >> mailcow.conf
+ echo '# If empty, it will completely disable Spamhaus blocklists if it detects that you are running on a server using a blocked AS.' >> mailcow.conf
+ echo '# Otherwise it will work as usual.' >> mailcow.conf
+ echo 'SPAMHAUS_DQS_KEY=' >> mailcow.conf
+ fi
+ elif [[ ${option} == "WATCHDOG_VERBOSE" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Enable watchdog verbose logging' >> mailcow.conf
+ echo 'WATCHDOG_VERBOSE=n' >> mailcow.conf
+ fi
+ elif [[ ${option} == "SKIP_UNBOUND_HEALTHCHECK" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Skip Unbound (DNS Resolver) Healthchecks (NOT Recommended!) - y/n' >> mailcow.conf
+ echo 'SKIP_UNBOUND_HEALTHCHECK=n' >> mailcow.conf
+ fi
+ elif [[ ${option} == "DISABLE_NETFILTER_ISOLATION_RULE" ]]; then
+ if ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo '# Prevent netfilter from setting an iptables/nftables rule to isolate the mailcow docker network - y/n' >> mailcow.conf
+ echo '# CAUTION: Disabling this may expose container ports to other neighbors on the same subnet, even if the ports are bound to localhost' >> mailcow.conf
+ echo 'DISABLE_NETFILTER_ISOLATION_RULE=n' >> mailcow.conf
+ fi
+ elif ! grep -q ${option} mailcow.conf; then
+ echo "Adding new option \"${option}\" to mailcow.conf"
+ echo "${option}=n" >> mailcow.conf
+ fi
+ done
+}
+
+migrate_solr_config_options() {
+
+ sed -i --follow-symlinks '$a\' mailcow.conf
+
+ if grep -q "SOLR_HEAP" mailcow.conf; then
+ echo "Removing SOLR_HEAP in mailcow.conf"
+ sed -i '/# Solr heap size in MB\b/d' mailcow.conf
+ sed -i '/# Solr is a prone to run\b/d' mailcow.conf
+ sed -i '/SOLR_HEAP\b/d' mailcow.conf
+ fi
+
+ if grep -q "SKIP_SOLR" mailcow.conf; then
+ echo "Removing SKIP_SOLR in mailcow.conf"
+ sed -i '/\bSkip Solr on low-memory\b/d' mailcow.conf
+ sed -i '/\bSolr is disabled by default\b/d' mailcow.conf
+ sed -i '/\bDisable Solr or\b/d' mailcow.conf
+ sed -i '/\bSKIP_SOLR\b/d' mailcow.conf
+ fi
+
+ if grep -q "SOLR_PORT" mailcow.conf; then
+ echo "Removing SOLR_PORT in mailcow.conf"
+ sed -i '/\bSOLR_PORT\b/d' mailcow.conf
+ fi
+
+ if grep -q "FLATCURVE_EXPERIMENTAL" mailcow.conf; then
+ echo "Removing FLATCURVE_EXPERIMENTAL in mailcow.conf"
+ sed -i '/\bFLATCURVE_EXPERIMENTAL\b/d' mailcow.conf
+ fi
+
+ solr_volume=$(docker volume ls -qf name=^${COMPOSE_PROJECT_NAME}_solr-vol-1)
+ if [[ -n $solr_volume ]]; then
+ echo -e "\e[34mSolr has been replaced within mailcow since 2024-12.\e[0m"
+ sleep 1
+ echo -e "\e[34mTherefore the volume $solr_volume is unused.\e[0m"
+ sleep 1
+ read -r -p "Would you like to remove the $solr_volume? " response
+ if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
+ echo -e "\e[33mRemoving $solr_volume...\e[0m"
+ docker volume rm $solr_volume
+ if [[ $? != 0 ]]; then
+ echo -e "\e[31mCould not remove the volume... Please remove it manually!\e[0m"
+ else
+ echo -e "\e[32mSucessfully removed $solr_volume!\e[0m"
+ fi
+ else
+ echo "Ok! Not removing $solr_volume then."
+ echo "Once you decided on removing the volume simply run docker volume rm $solr_volume to remove it manually."
+ echo "This can be done anytime. mailcow does not use this volume anymore."
+ fi
+ fi
+}
+
############## End Function Section ##############
# Check permissions
@@ -523,8 +917,6 @@ CONFIG_ARRAY=(
"MAILDIR_GC_TIME"
"MAILDIR_SUB"
"ACL_ANYONE"
- "SOLR_HEAP"
- "SKIP_SOLR"
"ENABLE_SSL_SNI"
"ALLOW_ADMIN_EMAIL_LOGIN"
"SKIP_HTTP_VERIFICATION"
@@ -651,21 +1043,6 @@ for option in "${CONFIG_ARRAY[@]}"; do
echo '# Otherwise a user might share data with too many other users.' >> mailcow.conf
echo 'ACL_ANYONE=disallow' >> mailcow.conf
fi
- elif [[ "${option}" == "SOLR_HEAP" ]]; then
- if ! grep -q "${option}" mailcow.conf; then
- echo "Adding new option \"${option}\" to mailcow.conf"
- echo '# Solr heap size, there is no recommendation, please see Solr docs.' >> mailcow.conf
- echo '# Solr is a prone to run OOM on large systems and should be monitored. Unmonitored Solr setups are not recommended.' >> mailcow.conf
- echo '# Solr will refuse to start with total system memory below or equal to 2 GB.' >> mailcow.conf
- echo "SOLR_HEAP=1024" >> mailcow.conf
- fi
- elif [[ "${option}" == "SKIP_SOLR" ]]; then
- if ! grep -q "${option}" mailcow.conf; then
- echo "Adding new option \"${option}\" to mailcow.conf"
- echo '# Solr is disabled by default after upgrading from non-Solr to Solr-enabled mailcows.' >> mailcow.conf
- echo '# Disable Solr or if you do not want to store a readable index of your mails in solr-vol-1.' >> mailcow.conf
- echo "SKIP_SOLR=y" >> mailcow.conf
- fi
elif [[ "${option}" == "ENABLE_SSL_SNI" ]]; then
if ! grep -q "${option}" mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
@@ -998,7 +1375,8 @@ for container in "${MAILCOW_CONTAINERS[@]}"; do
done
[[ -f data/conf/nginx/ZZZ-ejabberd.conf ]] && rm data/conf/nginx/ZZZ-ejabberd.conf
-
+migrate_solr_config_options
+adapt_new_options
# Silently fixing remote url from andryyy to mailcow
# git remote set-url origin https://github.com/mailcow/mailcow-dockerized
From de80c120c9cd4f41b75ba21ce3ad58a999fc6ea2 Mon Sep 17 00:00:00 2001
From: DerLinkman
Date: Thu, 12 Dec 2024 16:57:32 +0100
Subject: [PATCH 32/52] update.sh: added silent fix for removing old fts.conf
in order to update properly
---
update.sh | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/update.sh b/update.sh
index d488c4784..6d9f8dd7e 100755
--- a/update.sh
+++ b/update.sh
@@ -694,7 +694,15 @@ migrate_solr_config_options() {
echo "Once you decided on removing the volume simply run docker volume rm $solr_volume to remove it manually."
echo "This can be done anytime. mailcow does not use this volume anymore."
fi
- fi
+ fi
+
+ # Delete old fts.conf before forced switch to flatcurve to ensure update is working properly
+ FTS_CONF_PATH="data/conf/dovecot/conf.d/fts.conf"
+ if [[ -f "$FTS_CONF_PATH" ]]; then
+ if grep -q "Autogenerated by mailcow" "$FTS_CONF_PATH"; then
+ rm -rf $FTS_CONF_PATH
+ fi
+ fi
}
############## End Function Section ##############
From 1c6684a5392ec66332a1e70653c50cce23114dd6 Mon Sep 17 00:00:00 2001
From: DerLinkman
Date: Thu, 12 Dec 2024 17:02:21 +0100
Subject: [PATCH 33/52] compose: fix dovecot tagging
---
docker-compose.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docker-compose.yml b/docker-compose.yml
index 55481fb50..fc2ad58ca 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -229,7 +229,7 @@ services:
- sogo
dovecot-mailcow:
- image: mailcow/dovecot:2.21
+ image: mailcow/dovecot:2.3
depends_on:
- mysql-mailcow
- netfilter-mailcow
From 357a4d7fb34b3714f9274b3d98fbaa0e78885fc8 Mon Sep 17 00:00:00 2001
From: milkmaker
Date: Fri, 13 Dec 2024 12:21:12 +0100
Subject: [PATCH 34/52] [Web] Updated lang.fr-fr.json (#6209)
Co-authored-by: Neuronnexion
---
data/web/lang/lang.fr-fr.json | 71 ++++++++++++++++++++---------------
1 file changed, 40 insertions(+), 31 deletions(-)
diff --git a/data/web/lang/lang.fr-fr.json b/data/web/lang/lang.fr-fr.json
index 7348b6b5e..adcbd2a28 100644
--- a/data/web/lang/lang.fr-fr.json
+++ b/data/web/lang/lang.fr-fr.json
@@ -3,13 +3,13 @@
"alias_domains": "Ajouter un alias de domaine",
"app_passwds": "Gérer les mots de passe d'application",
"bcc_maps": "Mapping BCC",
- "delimiter_action": "Délimitation d'action",
+ "delimiter_action": "Action du délimiteur",
"eas_reset": "Réinitialiser les périphériques EA",
"extend_sender_acl": "Autoriser l'extension des ACL par des adresses externes",
"filters": "Filtres",
"login_as": "S'identifier en tant qu'utilisateur",
"prohibited": "Interdit par les ACL",
- "protocol_access": "Modifier le protocol d'acces",
+ "protocol_access": "Modifier le protocole d’accès",
"pushover": "Pushover",
"quarantine": "Actions de quarantaine",
"quarantine_attachments": "Pièces jointes en quarantaine",
@@ -20,7 +20,7 @@
"smtp_ip_access": "Changer les hôtes autorisés pour SMTP",
"sogo_access": "Autoriser la gestion des accès à SOGo",
"sogo_profile_reset": "Réinitialiser le profil SOGo",
- "spam_alias": "Alias temporaire",
+ "spam_alias": "Alias temporaires",
"spam_policy": "Liste Noire/Liste Blanche",
"spam_score": "Score SPAM",
"syncjobs": "Tâches de synchronisation",
@@ -48,13 +48,13 @@
"comment_info": "Un commentaire privé n'est pas visible pour l'utilisateur, tandis qu'un commentaire public est affiché sous forme d'info-bulle lorsqu'on le survole dans un aperçu des utilisateurs",
"custom_params": "Paramètres personnalisés",
"custom_params_hint": "Correct : --param=xy, Incorrect : --param xy",
- "delete1": "Supprimer à la source lorsque la synchronisation terminée",
- "delete2": "Supprimer les messages à destination qui ne sont pas présents à la source",
- "delete2duplicates": "Supprimer les doubles à destination",
+ "delete1": "Supprimer sur la source lorsque la synchronisation est terminée",
+ "delete2": "Supprimer les messages sur la destination qui ne sont pas présents sur la source",
+ "delete2duplicates": "Supprimer les doublons sur la destination",
"description": "Description",
"destination": "Destination",
"disable_login": "Désactiver l'authentification (les courriels entrants resteront acceptés)",
- "domain": "domaine",
+ "domain": "Domaine",
"domain_matches_hostname": "Le domaine %s correspond à la machine (hostname)",
"domain_quota_m": "Quota total du domaine (Mo)",
"enc_method": "Méthode de chiffrement",
@@ -80,7 +80,7 @@
"password": "Mot de passe",
"password_repeat": "Confirmation du mot de passe (répéter)",
"port": "Port",
- "post_domain_add": "le conteneur SOGo, \"sogo-mailcow\", doit être redémarré après l'ajout d'un nouveau domaine!
De plus, la configuration DNS doit être révisée. Lorsque la configuration DNS est approuvée, redémarrer \"acme-mailcow\" pour générer automatiquement les certificats pour votre nouveau domaine (autoconfig.<domain>, autodiscover.<domain>).
Cette étape est optionelle et sera réessayée toutes les 24 heures.",
+ "post_domain_add": "Le conteneur SOGo, « sogo-mailcow », doit être redémarré après l'ajout d'un nouveau domaine !
De plus, la configuration DNS doit être révisée. Lorsque la configuration DNS est approuvée, redémarrer « acme-mailcow » pour générer automatiquement les certificats pour votre nouveau domaine (autoconfig.<domain>, autodiscover.<domain>).
Cette étape est optionnelle et sera réessayée toutes les 24 heures.",
"private_comment": "Commentaire privé",
"public_comment": "Commentaire public",
"quota_mb": "Quota (Mo)",
@@ -286,7 +286,7 @@
"rspamd_settings_map": "Carte des paramètres Rspamd",
"sal_level": "Niveau Moo",
"save": "Enregistrer les modifications",
- "search_domain_da": "Recherche domaines",
+ "search_domain_da": "Rechercher des domaines",
"send": "Envoyer",
"sender": "Expéditeur",
"service_id": "ID du service",
@@ -415,7 +415,7 @@
"mailboxes_in_use": "Le max. des boîtes de réception doit être supérieur ou égal à %d",
"malformed_username": "Nom d’utilisateur malformé",
"map_content_empty": "Le contenu de la carte ne peut pas être vide",
- "max_alias_exceeded": "Le nombre max. d'aliases est dépassé",
+ "max_alias_exceeded": "Le nombre max. d'alias est dépassé",
"max_mailbox_exceeded": "Le nombre max. de boîte de réception est dépassé (%d of %d)",
"max_quota_in_use": "Le quota de la boîte de réception doit être supérieur ou égal à %d Mo",
"maxquota_empty": "Le quota maximum par boîte de réception ne doit pas être de 0.",
@@ -515,7 +515,9 @@
"wip": "En cours de réalisation",
"architecture": "Architecture",
"cores": "Cœurs",
- "current_time": "Heure du système"
+ "current_time": "Heure du système",
+ "container_disabled": "Conteneur arrêté ou désactivé",
+ "error_show_ip": "Impossible de résoudre les adresses IP publiques"
},
"diagnostics": {
"cname_from_a": "Valeur dérivée de l’enregistrement A/AAAA. Ceci est supporté tant que l’enregistrement indique la bonne ressource.",
@@ -526,7 +528,7 @@
"dns_records_name": "Nom",
"dns_records_status": "État courant",
"dns_records_type": "Type",
- "optional": "Cet enregistrement est optionel."
+ "optional": "Cet enregistrement est optionnel."
},
"edit": {
"active": "Actif",
@@ -545,7 +547,7 @@
"comment_info": "Un commentaire privé n’est pas visible pour l’utilisateur, tandis qu’un commentaire public est affiché comme infobulle lorsque vous le placez dans un aperçu des utilisateurs",
"delete1": "Supprimer de la source une fois terminé",
"delete2": "Supprimer les messages sur la destination qui ne sont pas sur la source",
- "delete2duplicates": "Supprimer les doublons à destination",
+ "delete2duplicates": "Supprimer les doublons sur la destination",
"delete_ays": "Veuillez confirmer le processus de suppression.",
"description": "Description",
"disable_login": "Refuser l’ouverture de session (le courrier entrant est toujours accepté)",
@@ -660,7 +662,8 @@
"mailbox_rename": "Renommer la boîte de réception",
"mailbox_rename_agree": "J'ai fait une sauvegarde.",
"mailbox_rename_warning": "IMPORTANT ! Faites une sauvegarde avant de renommer la boîte de réception.",
- "mailbox_rename_alias": "Créer un alias automatiquement"
+ "mailbox_rename_alias": "Créer un alias automatiquement",
+ "sogo_access": "Autoriser la connexion directe à SOGo"
},
"footer": {
"cancel": "Annuler",
@@ -725,9 +728,9 @@
"add_tls_policy_map": "Ajouter la carte de la politique des TLS",
"address_rewriting": "Réécriture de l’adresse",
"alias": "Alias",
- "alias_domain_alias_hint": "Les alias ne sont pas appliqués automatiquement sur les alias de domaine. Un alias d'adresse my-alias@domain ne couvre pas l'adresse my-alias@alias-domain (où \"alias-domain\" est un alias imaginaire pour \"domain\").
Veuillez utiliser un filtre à tamis pour rediriger le courrier vers une boîte de réception externe (voir l'onglet « Filtres » ou utilisez SOGo → Transférer).",
+ "alias_domain_alias_hint": "Les alias ne sont pas appliqués automatiquement sur les alias de domaine. Un alias d'adresse my-alias@domain ne couvre pas l'adresse my-alias@alias-domain (où « alias-domain » est un alias imaginaire pour « domain »).
Veuillez utiliser un filtre sieve pour rediriger le courrier vers une boîte de réception externe (voir l'onglet « Filtres » ou utilisez SOGo → Transférer). Utilisez « Étendre l'alias aux alias de domaine » pour ajouter automatiquement les alias manquants.",
"alias_domain_backupmx": "Alias de domaine inactif pour le domaine relais",
- "aliases": "Aliases",
+ "aliases": "Alias",
"allow_from_smtp": "Restreindre l'utilisation de SMTP à ces adresses IP",
"allow_from_smtp_info": "Laissez vide pour autoriser tous les expéditeurs.
Adresses IPv4/IPv6 et réseaux.",
"allowed_protocols": "Protocoles autorisés",
@@ -820,7 +823,7 @@
"running": "En fonctionnement",
"set_postfilter": "Marquer comme postfiltre",
"set_prefilter": "Marquer comme préfiltre",
- "sieve_info": "Vous pouvez stocker plusieurs filtres par utilisateur, mais un seul préfiltre et un seul postfiltre peuvent être actifs simultanément.
\nChaque filtre sera traité dans l’ordre décrit. Ni un script « rejeter » ni un « garder » n’arrêtera le traitement des autres scripts. Les modifications apportées aux scripts de tamis globaux déclencheront un redémarrage de Dovecot.
Préfiltre de tamis global → Préfiltre → Scripts utilisateur → Postfiltre → Postfiltre du tamis global",
+ "sieve_info": "Vous pouvez stocker plusieurs filtres par utilisateur, mais un seul préfiltre et un seul postfiltre peuvent être actifs simultanément.
\nChaque filtre sera traité dans l’ordre décrit. Ni un script en échec ni un « keep; » n’arrêtera le traitement des autres scripts. Les modifications apportées aux scripts sieve globaux déclencheront un redémarrage de Dovecot.
Préfiltre sieve global → Préfiltre → Scripts utilisateur → Postfiltre → Postfiltre sieve global",
"sieve_preset_1": "Jeter le courrier avec les types de fichiers dangereux probables",
"sieve_preset_2": "Toujours marquer l'adresse de courriel d’un expéditeur spécifique comme vu",
"sieve_preset_3": "Jeter en silence, arrêter tout traitement supplémentaire par filtre sieve",
@@ -866,7 +869,9 @@
"mailbox_templates": "Modèle de boîte de réception",
"relay_unknown": "Relayer les boîtes de réception inconnues",
"all_domains": "Tous les domaines",
- "syncjob_EXIT_OVERQUOTA": "Quota dépassé de la boîte de réception cible"
+ "syncjob_EXIT_OVERQUOTA": "Quota dépassé de la boîte de réception cible",
+ "domain_templates": "Modèles de domaine",
+ "syncjob_last_run_result": "Résultat de la dernière exécution"
},
"oauth2": {
"access_denied": "Veuillez vous connecter en tant que propriétaire de la boîte de réception pour accorder l’accès via Oauth2.",
@@ -939,7 +944,8 @@
"hold_mail_legend": "Met en attente les courriers sélectionnés. (Empêche les tentatives de distribution ultérieures)",
"unban": "file d'attente d'unban",
"unhold_mail": "Libérer",
- "unhold_mail_legend": "Libère les courriers sélectionnés pour la distribution. (Nécessite une mise en attente préalable)"
+ "unhold_mail_legend": "Libère les courriers sélectionnés pour la distribution. (Nécessite une mise en attente préalable)",
+ "show_message": "Afficher le message"
},
"start": {
"help": "Afficher/masquer le panneau d’aide",
@@ -962,14 +968,14 @@
"app_links": "Modifications enregistrées dans les liens d’application",
"app_passwd_added": "Ajout d’un nouveau mot de passe d’application",
"app_passwd_removed": "Suppression de l’identifiant du mot de passe de l’application %s",
- "bcc_deleted": "Suppression des entrées de la carte BCC : %s",
+ "bcc_deleted": "Suppression des entrées de la carte BCC : %s",
"bcc_edited": "Entrée de la carte BCC %s modifiée",
"bcc_saved": "Saisie de carte BCC enregistrée",
"db_init_complete": "Initialisation de la base de données terminée",
"delete_filter": "ID des filtres supprimés %s",
"delete_filters": "Filtres supprimés : %s",
- "deleted_syncjob": "ID du travail de synchronisation supprimé : %s",
- "deleted_syncjobs": "Travail de synchronisation supprimé : %s",
+ "deleted_syncjob": "ID de la tâche de synchronisation supprimée : %s",
+ "deleted_syncjobs": "Tâche de synchronisation supprimée : %s",
"dkim_added": "La clé DKIM %s a été enregistrée",
"dkim_duplicated": "La clé DKIM pour le domaine %s a été copiée vers %s",
"dkim_removed": "La clé DKIM %s a été supprimée",
@@ -1105,7 +1111,7 @@
"daily": "Quotidien",
"day": "jour",
"delete_ays": "Veuillez confirmer le processus de suppression.",
- "direct_aliases": "Adresses alias directes",
+ "direct_aliases": "Adresses d'alias directes",
"direct_aliases_desc": "Les adresses d’alias directes sont affectées par le filtre anti-spam et les paramètres de politique TLS.",
"eas_reset": "Réinitialiser le cache de l’appareil ActiveSync",
"eas_reset_help": "Dans de nombreux cas, une réinitialisation du cache de l’appareil aidera à récupérer un profil ActiveSync cassé.
Attention : Tous les éléments seront de nouveau téléchargés !",
@@ -1170,7 +1176,7 @@
"spamfilter": "Filtre de spam",
"spamfilter_behavior": "Note",
"spamfilter_bl": "Liste noire (BlackList)",
- "spamfilter_bl_desc": "Les adresses de courriel sur la liste noire de toujours peuvent être classées comme des pourriels et rejetées. Des caractères génériques peuvent être utilisés. Un filtre n’est appliqué qu’aux alias directs (alias avec une seule boîte de réception cible), à l’exclusion des alias tous azimuts et d’une boîte de réception elle-même.",
+ "spamfilter_bl_desc": "Les adresses de courriel sur liste noire qui doivent toujours être classées comme des pourriels et rejetées. Les messages rejetés ne seront pas copiés dans la quarantaine. Des caractères génériques peuvent être utilisés. Un filtre n’est appliqué qu’aux alias directs (alias avec une seule boîte de réception cible), à l’exclusion des alias attrape-tout et d’une boîte de réception elle-même.",
"spamfilter_default_score": "Valeurs par défaut",
"spamfilter_green": "Vert : ce message n'est pas un spam",
"spamfilter_hint": "La première valeur indique un « faible score de spam », la seconde représente un « haut score de spam ».",
@@ -1182,10 +1188,10 @@
"spamfilter_table_remove": "supprimer",
"spamfilter_table_rule": "Règle",
"spamfilter_wl": "Liste blanche (WhiteList)",
- "spamfilter_wl_desc": "La liste blanche est programmée pour ne jamais classer comme spam les adresses de courriel qu'elle contient. Des caractères génériques peuvent être utilisés. Un filtre n’est appliqué qu’aux alias directs (alias avec une seule boîte de réception cible), à l’exclusion des alias catch-all et d’une boîte de réception.",
+ "spamfilter_wl_desc": "La liste blanche est programmée pour ne jamais classer comme spam les adresses de courriel qu'elle contient. Des caractères génériques peuvent être utilisés. Un filtre n’est appliqué qu’aux alias directs (alias avec une seule boîte de réception cible), à l’exclusion des alias attrape-tout et d’une boîte de réception.",
"spamfilter_yellow": "Jaune : ce message est peut être un spam, il sera étiqueté comme spam et déplacé vers votre dossier Pourriel",
"status": "Statut",
- "sync_jobs": "Jobs de synchronisation",
+ "sync_jobs": "Tâches de synchronisation",
"tag_handling": "Régler la manipulation du courrier étiqueté",
"tag_help_example": "Exemple pour une adresse de courriel étiquetée : me+Facebook@example.org",
"tag_help_explain": "Dans un sous-dossier : un nouveau sous-dossier nommé selon l'étiquette sera créé sous INBOX (\"INBOX/Facebook\").
\nDans le sujet : le nom des balises sera ajouté au début du sujet de l'e-mail, exemple : \"[Facebook] My News\".",
@@ -1232,13 +1238,15 @@
"allowed_protocols": "Protocoles autorisés",
"mailbox": "Boîte de réception",
"password_reset_info": "Si aucun email pour la récupération du mot de passe n'est fourni, cette fonction ne peut pas être utilisée.",
- "pw_recovery_email": "Email de récupération pour son mot de passe"
+ "pw_recovery_email": "Email de récupération pour son mot de passe",
+ "month": "mois",
+ "from": "de"
},
"warning": {
"cannot_delete_self": "Impossible de supprimer l’utilisateur connecté",
"domain_added_sogo_failed": "Ajout d’un domaine mais échec du redémarrage de Sogo, veuillez vérifier les journaux de votre serveur.",
"dovecot_restart_failed": "Dovecot n’a pas pu redémarrer, veuillez vérifier les journaux",
- "fuzzy_learn_error": "Erreur d’apprentissage du hachage flou: %s",
+ "fuzzy_learn_error": "Erreur d’apprentissage du hachage flou : %s",
"hash_not_found": "Hachage non trouvé ou déjà supprimé",
"ip_invalid": "IP non valide ignorée : %s",
"no_active_admin": "Impossible de désactiver le dernier administrateur actif",
@@ -1259,13 +1267,14 @@
"sortAscending": ": activer pour trier les colonnes en ordre croissant",
"sortDescending": ": activer pour trier les colonnes en ordre décroissant"
},
- "infoEmpty": "Affichage de 0 à 0 de 0 entrées",
- "infoFiltered": "(filtré à partir de _MAX_ entrées totales)",
+ "infoEmpty": "Affichage de 0 à 0 sur 0 entrée",
+ "infoFiltered": "(filtré à partir de _MAX_ entrée(s) totale(s))",
"lengthMenu": "Afficher les entrées _MENU_",
"loadingRecords": "Chargement…",
"processing": "Veuillez patienter…",
"collapse_all": "Tout réduire",
- "info": "Affichage de _START_ de _END_ sur _TOTAL_ entrées"
+ "info": "Affichage de _START_ à _END_ sur _TOTAL_ entrée(s)",
+ "search": "Rechercher :"
},
"ratelimit": {
"disabled": "Désactivé"
From c6f6eda0bffce56169e55c9bfc41fe41ff5b249d Mon Sep 17 00:00:00 2001
From: Jan Oratowski <54535207+jan-oratowski@users.noreply.github.com>
Date: Sat, 14 Dec 2024 15:27:37 +0100
Subject: [PATCH 35/52] Fix missing property in Create Sync Job request
In example there was property called "user1", but it was missing from request definition.
This resulted in nswagger generating incorrect C# API code.
---
data/web/api/openapi.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/data/web/api/openapi.yaml b/data/web/api/openapi.yaml
index 09d613aa2..8f9e96590 100644
--- a/data/web/api/openapi.yaml
+++ b/data/web/api/openapi.yaml
@@ -1531,6 +1531,9 @@ paths:
port1:
description: the smtp port of the target mail server
type: string
+ user1:
+ description: the username of the mailbox
+ type: string
password:
description: the password of the mailbox
type: string
From 2d2dacb70efb8bb5a28cae66105185b10d0f8c96 Mon Sep 17 00:00:00 2001
From: milkmaker
Date: Thu, 19 Dec 2024 17:10:43 +0100
Subject: [PATCH 36/52] [Web] Updated lang.fr-fr.json (#6221)
[Web] Updated lang.fr-fr.json
Co-authored-by: Neuronnexion
Co-authored-by: Peter
---
data/web/lang/lang.fr-fr.json | 263 ++++++++++++++++++++--------------
1 file changed, 159 insertions(+), 104 deletions(-)
diff --git a/data/web/lang/lang.fr-fr.json b/data/web/lang/lang.fr-fr.json
index adcbd2a28..0e250b0ae 100644
--- a/data/web/lang/lang.fr-fr.json
+++ b/data/web/lang/lang.fr-fr.json
@@ -4,7 +4,7 @@
"app_passwds": "Gérer les mots de passe d'application",
"bcc_maps": "Mapping BCC",
"delimiter_action": "Action du délimiteur",
- "eas_reset": "Réinitialiser les périphériques EA",
+ "eas_reset": "Réinitialiser les périphériques EAS",
"extend_sender_acl": "Autoriser l'extension des ACL par des adresses externes",
"filters": "Filtres",
"login_as": "S'identifier en tant qu'utilisateur",
@@ -43,11 +43,11 @@
"alias_domain_info": "Seulement des noms de domaines valides (séparés par des virgules).",
"app_name": "Nom de l'application",
"app_password": "Mot de passe de l'application",
- "automap": "Tenter de cibler automatiquement les dossiers (\"Sent items\", \"Sent\" => \"Sent\" etc.)",
+ "automap": "Tenter de cibler automatiquement les dossiers (« Sent items », « Sent » => « Sent » etc.)",
"backup_mx_options": "Options de MX secondaire",
"comment_info": "Un commentaire privé n'est pas visible pour l'utilisateur, tandis qu'un commentaire public est affiché sous forme d'info-bulle lorsqu'on le survole dans un aperçu des utilisateurs",
"custom_params": "Paramètres personnalisés",
- "custom_params_hint": "Correct : --param=xy, Incorrect : --param xy",
+ "custom_params_hint": "Correct : --param=xy, incorrect : --param xy",
"delete1": "Supprimer sur la source lorsque la synchronisation est terminée",
"delete2": "Supprimer les messages sur la destination qui ne sont pas présents sur la source",
"delete2duplicates": "Supprimer les doublons sur la destination",
@@ -85,11 +85,11 @@
"public_comment": "Commentaire public",
"quota_mb": "Quota (Mo)",
"relay_all": "Relayer tous les destinataires",
- "relay_all_info": "↪ Si vous choissisez de ne pas relayer tous les destinataires, vous devez ajouter une boîte de réception (\"aveugle\") pour chaque destinataire simple qui doit être relayé.",
+ "relay_all_info": "↪ Si vous choisissez de ne pas relayer tous les destinataires, vous devez ajouter une boîte de réception (« aveugle ») pour chaque destinataire simple qui doit être relayé.",
"relay_domain": "Relayer ce domaine",
- "relay_transport_info": "Info
Vous pouvez définir des cartes de transport vers une destination personnalisée pour ce domaine. sinon, une recherche MX sera effectuée.",
+ "relay_transport_info": "Info
Vous pouvez définir des cartes de transport vers une destination personnalisée pour ce domaine. Sinon, une recherche MX sera effectuée.",
"relay_unknown_only": "Relayer uniquement les boîtes de réception inexistantes. Les boîtes de réception existantes seront livrées localement.",
- "relayhost_wrapped_tls_info": "Veuillez ne pas utiliser des ports TLS wrappés (généralement utilisés sur le port 465).
\r\nUtilisez n'importe quel port non encapsulé et lancez STARTTLS. Une politique TLS pour appliquer TLS peut être créée dans \"Cartes de politique TLS\".",
+ "relayhost_wrapped_tls_info": "Veuillez ne pas utiliser des ports TLS wrappés (généralement utilisés sur le port 465).
\nUtilisez n'importe quel port non encapsulé et lancez STARTTLS. Une politique TLS pour appliquer TLS peut être créée dans « Cartes de politique TLS ».",
"select": "Veuillez sélectionner…",
"select_domain": "Sélectionner d'abord un domaine",
"sieve_desc": "Description courte",
@@ -139,15 +139,15 @@
"api_skip_ip_check": "Passer la vérification d'IP pour l'API",
"app_links": "Liens des applications",
"app_name": "Nom de l'application",
- "apps_name": "\"mailcow Apps\" nom",
+ "apps_name": "Nom « mailcow Apps »",
"arrival_time": "Heure d'arrivée (heure du serveur)",
"authed_user": "Utilisateur autorisé",
"ays": "Voulez-vous vraiment le faire ?",
- "ban_list_info": "Consultez la liste des adresses IP bannies ci-dessous : réseau (durée de bannissement restante) - [actions].
Les adresses IP mises en file d'attente pour être dé-bannies seront supprimées de la liste de bannissement dans quelques secondes.
Les étiquettes rouges indiquent les bannissement permanent par liste noire.",
+ "ban_list_info": "Consultez la liste des adresses IP bannies ci-dessous : réseau (durée de bannissement restante) - [actions].
Les adresses IP mises en file d'attente pour être dé-bannies seront supprimées de la liste de bannissement dans quelques secondes.
Les étiquettes rouges indiquent les bannissements permanent par liste noire.",
"change_logo": "Changer de logo",
"configuration": "Configuration",
"convert_html_to_text": "Convertir le code HTML en texte brut",
- "credentials_transport_warning": "Attention : L’ajout d’une nouvelle entrée de carte de transport mettra à jour les informations d’identification pour toutes les entrées avec une colonne nexthop.",
+ "credentials_transport_warning": "Attention : L’ajout d’une nouvelle entrée de carte de transport mettra à jour les informations d’identification pour toutes les entrées avec une colonne nexthop.",
"customer_id": "ID client",
"customize": "Personnaliser",
"destination": "Destination",
@@ -184,7 +184,7 @@
"f2b_netban_ipv4": "Taille du sous-réseau IPv4 pour l'application du bannissement (8-32)",
"f2b_netban_ipv6": "Taille du sous-réseau IPv6 pour l'application du bannissement (8-128)",
"f2b_parameters": "Paramètres Fail2ban",
- "f2b_regex_info": "Logs pris en compte : SOGo, Postfix, Dovecot, PHP-FPM.",
+ "f2b_regex_info": "Logs pris en compte : SOGo, Postfix, Dovecot, PHP-FPM.",
"f2b_retry_window": "Fenêtre de nouvel essai pour le nb max. de tentatives",
"f2b_whitelist": "Réseaux/hôtes en liste blanche",
"filter_table": "Table de filtrage",
@@ -200,19 +200,19 @@
"host": "Hôte",
"html": "HTML",
"import": "Importer",
- "import_private_key": "Importer la clè privée",
+ "import_private_key": "Importer la clé privée",
"in_use_by": "Utilisé par",
"inactive": "Inactif",
"include_exclude": "Inclure/Exclure",
"include_exclude_info": "Par défaut - sans sélection - toutes les boîte de réception sont adressées",
"includes": "Inclure ces destinataires",
"last_applied": "Dernière application",
- "license_info": "Une licence n’est pas requise, mais contribue au développement.
Enregistrer votre GUID ici ou acheter le support pour votre installation Mailcow.",
+ "license_info": "Une licence n’est pas requise, mais contribue au développement.
Enregistrer votre GUID ici ou acheter le support pour votre installation mailcow.",
"link": "Lien",
"loading": "Veuillez patienter…",
"logo_info": "Votre image sera redimensionnée à une hauteur de 40 pixels pour la barre de navigation du haut et à un maximum de 250 pixels en largeur pour la page d'accueil. Un graphique extensible est fortement recommandé.",
"lookup_mx": "Faire correspondre la destination à MX (.*\\.google\\.com pour acheminer tous les messages ciblés vers un MX se terminant par google.com sur ce tronçon)",
- "main_name": "\"mailcow UI\" nom",
+ "main_name": "Nom « mailcow UI »",
"merged_vars_hint": "Les lignes grisées ont été importées depuis vars.(local.)inc.php et ne peuvent pas être modifiées.",
"message": "Message",
"message_size": "Taille du message",
@@ -223,7 +223,7 @@
"no_record": "Aucun enregistrement",
"oauth2_client_id": "Client ID",
"oauth2_client_secret": "Secret client",
- "oauth2_info": "L'implémentation OAuth2 prend en charge le type d'autorisation \"Authorization Code\" et émet des jetons d'actualisation.
\nLe serveur émet également automatiquement de nouveaux jetons d'actualisation, après qu'un jeton d'actualisation a été utilisé.
\n→ La portée par défaut est profile. Seuls les utilisateurs d'une boîte de réception peuvent être authentifiés par rapport à OAuth2. Si le paramètre scope est omis, il revient au profile.
\n→ Le paramètre state doit être envoyé par le client dans le cadre de la demande d'autorisation.
\nChemins d'accès aux requêtes vers l'API OAuth
\n\n - Point de terminaison d'autorisation :
/oauth/authorize \n - Point de terminaison du jeton :
/oauth/token \n - Page de ressource :
/oauth/profile \n
\nLa régénération du secret client ne fera pas expirer les codes d'autorisation existants, mais ils ne pourront pas renouveler leur jeton.
\nLa révocation des jetons clients entraînera la fin immédiate de toutes les sessions actives. Tous les clients doivent se ré-authentifier.",
+ "oauth2_info": "L'implémentation OAuth2 prend en charge le type d'autorisation « Authorization Code » et émet des jetons d'actualisation.
\nLe serveur émet également automatiquement de nouveaux jetons d'actualisation, après qu'un jeton d'actualisation a été utilisé.
\n→ La portée par défaut est profile. Seuls les utilisateurs d'une boîte de réception peuvent être authentifiés par rapport à OAuth2. Si le paramètre scope est omis, il revient au profile.
\n→ Le paramètre state doit être envoyé par le client dans le cadre de la demande d'autorisation.
\nChemins d'accès aux requêtes vers l'API OAuth
\n\n - Point de terminaison d'autorisation :
/oauth/authorize \n - Point de terminaison du jeton :
/oauth/token \n - Page de ressource :
/oauth/profile \n
\nLa régénération du secret client ne fera pas expirer les codes d'autorisation existants, mais ils ne pourront pas renouveler leur jeton.
\nLa révocation des jetons clients entraînera la fin immédiate de toutes les sessions actives. Tous les clients doivent se ré-authentifier.",
"oauth2_redirect_uri": "URI de redirection",
"oauth2_renew_secret": "Générer un nouveau secret client",
"oauth2_revoke_tokens": "Révoquer tous les jetons",
@@ -233,19 +233,19 @@
"priority": "Priorité",
"private_key": "Clé privée",
"quarantine": "Quarantaine",
- "quarantine_bcc": "Envoyer une copie de toutes les notifications (BCC) à ce destinataire:
Laisser vide pour le désactiver. Courrier non signé et non coché. Doit être livré en l’interne seulement.",
+ "quarantine_bcc": "Envoyer une copie de toutes les notifications (BCC) à ce destinataire :
Laisser vide pour le désactiver. Courrier non signé et non coché. Doit être livré en interne seulement.",
"quarantine_exclude_domains": "Exclure les domaines et les alias de domaine",
"quarantine_max_age": "Âge maximun en jour(s)
La valeur doit être égale ou supérieure à 1 jour.",
- "quarantine_max_size": "Taille maximum en Mo (les éléments plus grands sont mis au rebut):
0 ne signifie pas illimité.",
- "quarantine_max_score": "Ignorer la notification si le score de spam est au dessus de cette valeur :
Par défaut : 9999.0",
+ "quarantine_max_size": "Taille maximum en Mo (les éléments plus grands sont mis au rebut) :
0 ne signifie pas illimité.",
+ "quarantine_max_score": "Ignorer la notification si le score de spam est au dessus de cette valeur :
Par défaut : 9999.0",
"quarantine_notification_html": "Modèle de courriel de notification :
Laisser vide pour restaurer le modèle par défaut.",
"quarantine_notification_sender": "Notification par courriel de l’expéditeur",
"quarantine_notification_subject": "Objet du courriel de notification",
- "quarantine_redirect": "Rediriger toutes les notifications vers ce destinataire:
Laisser vide pour désactiver. Courrier non signé et non coché. Doit être livré en interne seulement.",
+ "quarantine_redirect": "Rediriger toutes les notifications vers ce destinataire :
Laisser vide pour désactiver. Courrier non signé et non coché. Doit être livré en interne seulement.",
"quarantine_release_format": "Format des éléments diffusés",
"quarantine_release_format_att": "En pièce jointe",
"quarantine_release_format_raw": "Original non modifié",
- "quarantine_retention_size": "Rétentions par boîte de réception:
0 indique inactive.",
+ "quarantine_retention_size": "Rétentions par boîte de réception :
0 indique inactive.",
"quota_notification_html": "Modèle de courriel de notification :
Laisser vide pour restaurer le modèle par défaut.",
"quota_notification_sender": "Notification par courriel de l’expéditeur",
"quota_notification_subject": "Objet du courriel de notification",
@@ -263,7 +263,7 @@
"relay_from": "\"De:\" adresse",
"relay_run": "Lancer le test",
"relayhosts": "Transports dépendant de l’expéditeur",
- "relayhosts_hint": "Définir les transports dépendant de l’expéditeur pour pouvoir les sélectionner dans un dialogue de configuration de domaines.
\n Le service de transport est toujours \"SMTP:\" et va donc essayer TLS lorsqu’il est proposé. Le TLS encapsulé (SMTPS) n’est pas pris en charge. Il est tenu compte de la définition de la politique TLS pour chaque utilisateur sortant.
\n Affecte les domaines sélectionnés, y compris les domaines alias.",
+ "relayhosts_hint": "Définir les transports dépendant de l’expéditeur pour pouvoir les sélectionner dans un dialogue de configuration de domaines.
\n Le service de transport est toujours « smtp: » et va donc essayer TLS lorsqu’il est proposé. Le TLS encapsulé (SMTPS) n’est pas pris en charge. Il est tenu compte de la définition de la politique TLS pour chaque utilisateur sortant.
\n Affecte les domaines sélectionnés, y compris les domaines alias.",
"remove": "Supprimer",
"remove_row": "Supprimer la ligne",
"reset_default": "Réinitialisation à la valeur par défaut",
@@ -274,7 +274,7 @@
"rsetting_desc": "Description courte",
"rsetting_no_selection": "Veuillez sélectionner une règle",
"rsetting_none": "Pas de règles disponibles",
- "rsettings_insert_preset": "Insérer un exemple de préréglage \"%s\"",
+ "rsettings_insert_preset": "Insérer un exemple de préréglage « %s »",
"rsettings_preset_1": "Désactiver tout sauf DKIM et la limite d'envoi pour les utilisateurs authentifiés",
"rsettings_preset_2": "Les postmasters veulent du spam",
"rsettings_preset_3": "Autoriser uniquement des expéditeurs particuliers pour une boîte de réception (c.-à-d. utilisation comme boîte de réception interne seulement)",
@@ -297,11 +297,11 @@
"text": "Texte",
"time": "Heure",
"title": "Titre",
- "title_name": "\"mailcow UI\" titre du site web",
+ "title_name": "Titre du site web « mailcow UI »",
"to_top": "Retour en haut",
"transport_dest_format": "Syntaxe : example.org, .example.org, *, box@example.org (les valeurs multiples peuvent être séparées par des virgules)",
"transport_maps": "Plans de transport",
- "transports_hint": "→ Une entrée de carte de transport annule une carte de transport dépendante de l’expéditeur.
\n→ Les transports basés sur le MX sont préférables.
\n→ Les paramètres de politique TLS sortants par utilisateur sont ignorés et ne peuvent être appliqués que par les entrées de carte de politique TLS.
\n→ Pour chaque transports défini, le servie de transports sera \"smtp:\", TLS sera essayé lorsque disponible. Le Wrapped TLS (SMTPS) n’est pas pris en charge.
\n→ Les adresses qui correspondent à\"/localhost$/\" seront toujours transportées via \"local:\", donc une destination \"*\" ne s'applique pas à ces adresses.
\n→ Pour déterminer les informations d'identification dans l'exemple suivant \"[host]:25\", Postfix va toujours faire une requête pour \"host\" avant de chercher \"[host]:25\". Ce comportement rend impossible l’utilisation \"host\" et \"[host]:25\" en même temps.",
+ "transports_hint": "→ Une entrée de carte de transport annule une carte de transport dépendante de l’expéditeur.
\n→ Les transports basés sur le MX sont préférables.
\n→ Les paramètres de politique TLS sortants par utilisateur sont ignorés et ne peuvent être appliqués que par les entrées de carte de politique TLS.
\n→ Pour chaque transports défini, le servie de transports sera « smtp: », TLS sera essayé lorsque disponible. Le Wrapped TLS (SMTPS) n’est pas pris en charge.
\n→ Les adresses qui correspondent à « /localhost$/ » seront toujours transportées via « local: », donc une destination « * » ne s'applique pas à ces adresses.
\n→ Pour déterminer les informations d'identification dans l'exemple suivant « [host]:25 », Postfix va toujours faire une requête pour « host » avant de chercher « [host]:25 ». Ce comportement rend impossible l’utilisation de « host » et « [host]:25 » en même temps.",
"ui_footer": "Pied de page (HTML autorisé)",
"ui_header_announcement": "Annonces",
"ui_header_announcement_active": "Définir l’annonce active",
@@ -352,7 +352,14 @@
"password_reset_tmpl_html": "Modèle HTML",
"password_reset_tmpl_text": "Modèle en texte",
"restore_template": "Laisser vide pour restaurer le modèle par défaut.",
- "admins_ldap": "Si aucune adresse de messagerie de récupération n'est fournie, cette fonction ne peut pas être utilisée."
+ "admins_ldap": "Administrateurs LDAP",
+ "options": "Options",
+ "ip_check_opt_in": "Utiliser le service tiers ipv4.mailcow.email et ipv6.mailcow.email pour résoudre les adresses IP externes.",
+ "queue_unban": "débannir",
+ "service": "Service",
+ "success": "Succès",
+ "cors_settings": "Paramètres CORS",
+ "login_time": "Horodatage de connexion"
},
"danger": {
"access_denied": "Accès refusé ou données de formulaire non valides",
@@ -370,37 +377,37 @@
"comment_too_long": "Le commentaire est trop long, 160 caractère max sont permis",
"defquota_empty": "Le quota par défaut par boîte de réception doit pas être 0.",
"description_invalid": "La description des ressources pour %s est non valide",
- "dkim_domain_or_sel_exists": "Une clé DKIM pour \"%s\" existe et ne sera pas écrasée",
- "dkim_domain_or_sel_invalid": "Domaine ou sélection DKIM non valide : %s",
+ "dkim_domain_or_sel_exists": "Une clé DKIM pour « %s » existe et ne sera pas écrasée",
+ "dkim_domain_or_sel_invalid": "Domaine ou sélecteur DKIM non valide : %s",
"domain_cannot_match_hostname": "Le domaine ne correspond pas au nom d’hôte",
"domain_exists": "Le domaine %s exite déjà",
"domain_invalid": "Le nom de domaine est vide ou non valide",
"domain_not_empty": "Impossible de supprimer le domaine non vide %s",
"domain_not_found": "Le domaine %s est introuvable",
"domain_quota_m_in_use": "Le quota de domaine doit être supérieur ou égal à %s Mo",
- "extra_acl_invalid": "L'adresse de l’expéditeur externe \"%s\" est non valide",
- "extra_acl_invalid_domain": "L'expéditeur externe \"%s\" utilise un domaine non valide",
+ "extra_acl_invalid": "L'adresse de l’expéditeur externe « %s » est non valide",
+ "extra_acl_invalid_domain": "L'expéditeur externe « %s » utilise un domaine non valide",
"file_open_error": "Le fichier ne peut pas être ouvert pour l'écriture",
"filter_type": "Type de fltre erroné",
"from_invalid": "Expéditeur ne peut pas être vide",
- "global_filter_write_error": "Impossible d’écrire le fichier de filtre : %s",
+ "global_filter_write_error": "Impossible d’écrire le fichier de filtre : %s",
"global_map_invalid": "ID de carte globale %s non valide",
- "global_map_write_error": "Impossible d’écrire l’ID de la carte globale %s : %s",
+ "global_map_write_error": "Impossible d’écrire l’ID de la carte globale %s : %s",
"goto_empty": "Une adresse alias doit contenir au moins une adresse 'goto'valide",
"goto_invalid": "Adresse Goto %s non valide",
- "ham_learn_error": "Erreur d'apprentissage Ham : %s",
- "imagick_exception": "Erreur : Exception Imagick lors de la lecture de l’image",
+ "ham_learn_error": "Erreur d'apprentissage Ham : %s",
+ "imagick_exception": "Erreur : Exception Imagick lors de la lecture de l’image",
"img_invalid": "Impossible de valider le fichier image",
- "img_tmp_missing": "Impossible de valider le fichier image : Fichier temporaire introuvable",
+ "img_tmp_missing": "Impossible de valider le fichier image : Fichier temporaire introuvable",
"invalid_bcc_map_type": "Type de carte BCC non valide",
- "invalid_destination": "Le format de la destination \"%s\" est non valide",
+ "invalid_destination": "Le format de la destination « %s » est non valide",
"invalid_filter_type": "Type de filtre non valide",
- "invalid_host": "Hôte non valide spécifié : %s",
+ "invalid_host": "Hôte non valide spécifié : %s",
"invalid_mime_type": "Type mime non valide",
"invalid_nexthop": "Le format de saut suivant est non valide",
"invalid_nexthop_authenticated": "Next hop existe avec différents identifiants, veuillez d’abord mettre à jour les identifiants existants pour ce prochain saut.",
- "invalid_recipient_map_new": "Nouveau destinataire spécifié non valide : %s",
- "invalid_recipient_map_old": "Destinataire original spécifié non valide : %s",
+ "invalid_recipient_map_new": "Nouveau destinataire spécifié non valide : %s",
+ "invalid_recipient_map_old": "Destinataire original spécifié non valide : %s",
"ip_list_empty": "La liste des adresses IP autorisées ne peut pas être vide",
"is_alias": "%s est déjà connu comme une adresse alias",
"is_alias_or_mailbox": "%s est déjà connu comme un alias, une boîte de réception ou une adresse alias développée à partir d’un domaine alias.",
@@ -411,7 +418,7 @@
"mailbox_invalid": "Le nom de la boîte de réception n'est pas valide",
"mailbox_quota_exceeded": "Le quota dépasse la limite du domaine (max. %d Mo)",
"mailbox_quota_exceeds_domain_quota": "Le quota maximal dépasse la limite du quota de domaine",
- "mailbox_quota_left_exceeded": "Espace libre insuffisant (espace libre : %d Mio)",
+ "mailbox_quota_left_exceeded": "Espace libre insuffisant (espace libre : %d Mio)",
"mailboxes_in_use": "Le max. des boîtes de réception doit être supérieur ou égal à %d",
"malformed_username": "Nom d’utilisateur malformé",
"map_content_empty": "Le contenu de la carte ne peut pas être vide",
@@ -419,9 +426,9 @@
"max_mailbox_exceeded": "Le nombre max. de boîte de réception est dépassé (%d of %d)",
"max_quota_in_use": "Le quota de la boîte de réception doit être supérieur ou égal à %d Mo",
"maxquota_empty": "Le quota maximum par boîte de réception ne doit pas être de 0.",
- "mysql_error": "Erreur MySQL : %s",
- "nginx_reload_failed": "Le rechargement de Nginx a échoué : %s",
- "network_host_invalid": "Réseau ou hôte non valide : %s",
+ "mysql_error": "Erreur MySQL : %s",
+ "nginx_reload_failed": "Le rechargement de Nginx a échoué : %s",
+ "network_host_invalid": "Réseau ou hôte non valide : %s",
"next_hop_interferes": "%s interfère avec le nexthop %s",
"next_hop_interferes_any": "Un saut suivant existant interfère avec %s",
"no_user_defined": "Aucun utilisateur défini",
@@ -432,15 +439,15 @@
"password_mismatch": "Le mot de passe de confirmation ne correspond pas",
"policy_list_from_exists": "Un enregistrement avec ce nom existe déjà",
"policy_list_from_invalid": "Le format de l’enregistrement est invalide",
- "private_key_error": "Erreur de clé privée : %s",
+ "private_key_error": "Erreur de clé privée : %s",
"pushover_credentials_missing": "Jeton Pushover ou clé manquante",
"pushover_key": "La clé Pushover a un mauvais format",
"pushover_token": "Le jeton Pushover a un mauvais format",
"quota_not_0_not_numeric": "Le quota doit être numerique et >= 0",
- "recipient_map_entry_exists": "Une entrée dans la carte du bénéficiaire \"%s\" existe",
- "redis_error": "Erreur Redis : %s",
+ "recipient_map_entry_exists": "Une entrée dans la carte du destinataire « %s » existe",
+ "redis_error": "Erreur Redis : %s",
"relayhost_invalid": "La saisie de la carte %s est invalide",
- "release_send_failed": "Le message n’a pas pu être diffusé : %s",
+ "release_send_failed": "Le message n’a pas pu être diffusé : %s",
"reset_f2b_regex": "Le filtre regex n'a pas pu être réinitialisé à temps, veuillez réessayer ou attendre quelques secondes de plus et recharger le site web.",
"resource_invalid": "Le nom de la resource %s n'est pas valide",
"rl_timeframe": "Le délai de la limite d'envoi est incorrect",
@@ -449,8 +456,8 @@
"sender_acl_invalid": "La valeur ACL de l’expéditeur %s est invalide",
"set_acl_failed": "Impossible de définir l'ACL",
"settings_map_invalid": "La carte des paramètres %s est invalide",
- "sieve_error": "Erreur d'analyse syntaxique Sieve : %s",
- "spam_learn_error": "Erreur d'apprentissage du spam : %s",
+ "sieve_error": "Erreur d'analyse syntaxique Sieve : %s",
+ "spam_learn_error": "Erreur d'apprentissage du spam : %s",
"subject_empty": "Le sujet ne peut pas être vide",
"target_domain_invalid": "Le domaine cible %s n'est pas valide",
"targetd_not_found": "Le domaine cible %s est introuvable",
@@ -459,19 +466,19 @@
"text_empty": "La zone texte ne peut pas être vide",
"tfa_token_invalid": "Le token TFA est invalide",
"tls_policy_map_dest_invalid": "La politique de destination n'est pas valide",
- "tls_policy_map_entry_exists": "Une entrée de carte de politique \"%s\" existe",
+ "tls_policy_map_entry_exists": "Une entrée de carte de politique « %s » existe",
"tls_policy_map_parameter_invalid": "Le paramètre Policy est invalide",
"totp_verification_failed": "Echec de la vérification TOTP",
- "transport_dest_exists": "La destination de transport \"%s\" existe",
- "webauthn_verification_failed": "Échec de la vérification WebAuthn : %s",
- "fido2_verification_failed": "La vérification FIDO2 a échoué : %s",
+ "transport_dest_exists": "La destination de transport « %s » existe",
+ "webauthn_verification_failed": "Échec de la vérification WebAuthn : %s",
+ "fido2_verification_failed": "La vérification FIDO2 a échoué : %s",
"unknown": "Une erreur inconnue est survenue",
"unknown_tfa_method": "Methode TFA inconnue",
"unlimited_quota_acl": "Quota illimité interdit par les ACL",
"username_invalid": "Le nom d'utilisateur %s ne peut pas être utilisé",
"validity_missing": "Veuillez attribuer une période de validité",
"value_missing": "Veuillez fournir toutes les valeurs",
- "yotp_verification_failed": "La vérification Yubico OTP a échoué : %s",
+ "yotp_verification_failed": "La vérification Yubico OTP a échoué : %s",
"webauthn_authenticator_failed": "L'authentificateur sélectionné est introuvable",
"demo_mode_enabled": "Le mode de démonstration est activé",
"template_exists": "Le modèle %s existe déjà",
@@ -479,7 +486,7 @@
"template_name_invalid": "Le nom du modèle est invalide",
"img_dimensions_exceeded": "L'image dépasse les dimensions maximales",
"img_size_exceeded": "L'image dépasse la taille maximale de fichier",
- "webauthn_publickey_failed": "Aucune clé publique n'a été stockée pour l'authentificateur sélectionné.",
+ "webauthn_publickey_failed": "Aucune clé publique n'a été stockée pour l'authentificateur sélectionné",
"cors_invalid_method": "Allow-Method specifiée invalide",
"cors_invalid_origin": "Allow-Origin spécifiée invalide",
"extended_sender_acl_denied": "ACL manquante pour définir les adresses des expéditeurs externes",
@@ -495,7 +502,7 @@
"chart_this_server": "Graphique (ce serveur)",
"containers_info": "Informations des conteneurs",
"disk_usage": "Utilisation du disque",
- "external_logs": "Logs externe",
+ "external_logs": "Logs externes",
"history_all_servers": "Historique (tous les serveurs)",
"in_memory_logs": "Logs En-mémoire",
"log_info": "Les logs En-mémoire Mailcow sont collectés dans des listes Redis et découpées en LOG_LINES (%d) chaque minute pour réduire la charge.\n
Les logs En-mémoire ne sont pas destinés à être persistants. Toutes les applications qui se connectent en mémoire, se connectent également au démon Docker, et donc au pilote de journalisation par défaut.\n
Le type de journal en mémoire doit être utilisé pour déboguer les problèmes mineurs avec les conteneurs.
\n Les logs externes sont collectés via l'API de l'application concernée.
\n Les journaux statiques sont principalement des journaux d’activité, qui ne sont pas enregistrés dans Dockerd, mais qui doivent toujours être persistants (sauf pour les logs API).
",
@@ -517,7 +524,17 @@
"cores": "Cœurs",
"current_time": "Heure du système",
"container_disabled": "Conteneur arrêté ou désactivé",
- "error_show_ip": "Impossible de résoudre les adresses IP publiques"
+ "error_show_ip": "Impossible de résoudre les adresses IP publiques",
+ "no_update_available": "Le système utilise la version la plus récente",
+ "container_running": "En cours d'exécution",
+ "container_stopped": "Arrêté",
+ "memory": "Mémoire",
+ "login_time": "Horodatage",
+ "service": "Service",
+ "success": "Succès",
+ "update_available": "Une mise à jour est disponible",
+ "update_failed": "Impossible de vérifier la présence d'une mise à jour",
+ "show_ip": "Afficher l'IP publique"
},
"diagnostics": {
"cname_from_a": "Valeur dérivée de l’enregistrement A/AAAA. Ceci est supporté tant que l’enregistrement indique la bonne ressource.",
@@ -539,7 +556,7 @@
"allowed_protocols": "Protocoles autorisés",
"app_name": "Nom de l'application",
"app_passwd": "Mot de passe de l'application",
- "automap": "Essayer d’automatiser les dossiers (\"Sent items\", \"Sent\" => \"Sent\" etc.)",
+ "automap": "Tenter de cibler automatiquement les dossiers (« Sent items », « Sent » => « Sent » etc.)",
"backup_mx_options": "Options Backup MX",
"bcc_dest_format": "La destination BCC doit être une seule adresse de courriel valide.",
"client_id": "ID client",
@@ -579,7 +596,7 @@
"max_quota": "Quota max. par boîte de réception (Mo)",
"maxage": "Âge maximal en jours des messages qui seront consultés à distance
(0 = ignorer la durée)",
"maxbytespersecond": "Octets max. par seconde
(0 = pas de limite)",
- "mbox_rl_info": "Cette limite d'envoi est appliquée au nom de connexion SASL, elle correspond à toute adresse \"from\" utilisée par l’utilisateur connecté. Une limite d'envoi pour les boîtes de réception remplace une limite d'envoi pour l’ensemble du domaine.",
+ "mbox_rl_info": "Cette limite d'envoi est appliquée au nom de connexion SASL, elle correspond à toute adresse « from » utilisée par l’utilisateur connecté. Une limite d'envoi pour les boîtes de réception remplace une limite d'envoi pour l’ensemble du domaine.",
"mins_interval": "Intervalle (min)",
"multiple_bookings": "Réservations multiples",
"nexthop": "Saut suivant",
@@ -601,7 +618,7 @@
"ratelimit": "Limite d'envoi",
"redirect_uri": "URL de redirection/callback",
"relay_all": "Relayer tous les destinataires",
- "relay_all_info": "↪ Si vous ne choisissez pas de relayer tous les destinataires, vous devrez ajouter une boîte de réception (\"aveugle\") pour chaque destinataire qui devrait être relayé.",
+ "relay_all_info": "↪ Si vous ne choisissez pas de relayer tous les destinataires, vous devrez ajouter une boîte de réception (« aveugle ») pour chaque destinataire qui devrait être relayé.",
"relay_domain": "Relayer ce domaine",
"relay_transport_info": "Info
Vous pouvez définir des cartes de transport vers une destination personnalisée pour ce domaine. Si elle n’est pas configurée, une recherche MX sera effectuée.",
"relay_unknown_only": "Relais des boîtes de réception non existantes seulement. Les boîtes de réception existantes seront livrées localement.",
@@ -612,7 +629,7 @@
"scope": "Portée",
"sender_acl": "Permettre d’envoyer comme",
"sender_acl_disabled": "Le contrôle de l’expéditeur est désactivé",
- "sender_acl_info": "Si l’utilisateur de la boîte de réception A est autorisé à envoyer en tant qu’utilisateur de la boîte de réception B, l’adresse de l’expéditeur n’est pas automatiquement affichée comme sélectionnable du champ \"de\" dans SOGo.
\n L’utilisateur B de la boîte de réception doit créer une délégation dans Sogo pour permettre à l’utilisateur A de la boîte de réception de sélectionner son adresse comme expéditeur. Pour déléguer une boîte de réception dans Sogo, utilisez le menu (trois points) à droite du nom de votre boîte dans le coin supérieur gauche dans la vue de courrier. Ce comportement ne s’applique pas aux adresses alias.",
+ "sender_acl_info": "Si l’utilisateur de la boîte de réception A est autorisé à envoyer en tant qu’utilisateur de la boîte de réception B, l’adresse de l’expéditeur n’est pas automatiquement affichée comme sélectionnable du champ « de » dans SOGo.
\n L’utilisateur B de la boîte de réception doit créer une délégation dans SOGo pour permettre à l’utilisateur A de la boîte de réception de sélectionner son adresse comme expéditeur. Pour déléguer une boîte de réception dans SOGo, utilisez le menu (trois points) à droite du nom de votre boîte dans le coin supérieur gauche dans la vue de courrier. Ce comportement ne s’applique pas aux adresses alias.",
"sieve_desc": "Description courte",
"sieve_type": "Type de filtre",
"skipcrossduplicates": "Ignorer les messages en double dans les dossiers (premier arrivé, premier servi)",
@@ -640,15 +657,15 @@
"domain_footer_info_vars": {
"from_addr": "{= from_addr =} - Partie de l'enveloppe relative à l'adresse de provenance",
"from_domain": "{= from_domain =} - Partie de l'enveloppe provenant du domaine",
- "custom": "{= foo =} - Si la boîte de réception possède l'attribut personnalisé \"foo\" avec la valeur \"bar\", elle renvoie \"bar\"",
+ "custom": "{= foo =} - Si la boîte de réception possède l'attribut personnalisé « foo » avec la valeur « bar », elle renvoie « bar »",
"auth_user": "{= auth_user =} - Nom d'utilisateur authentifié spécifié par un MTA",
- "from_user": "{= from_user =} -La partie utilisateur de l'enveloppe, par exemple, pour \"moo@mailcow.tld\", renvoie \"moo\"",
- "from_name": "{= from_name =} - À partir du nom de l'enveloppe, par exemple, pour \"Mailcow <moo@mailcow.tld> ;\" on obtient \"Mailcow\""
+ "from_user": "{= from_user =} -La partie utilisateur de l'enveloppe, par exemple, pour « moo@mailcow.tld », renvoie « moo »",
+ "from_name": "{= from_name =} - À partir du nom de l'enveloppe, par exemple, pour « Mailcow <moo@mailcow.tld> ; » on obtient « Mailcow »"
},
"domain_footer_skip_replies": "Ignorer le pied de page des courriels de réponse",
"domain_footer": "Pied de page du domaine",
"domain_footer_html": "Pied de page HTML",
- "domain_footer_info": "Les pieds de page du domaine sont ajoutés à tous les courriels sortants associés à une adresse au sein de ce domaine.
Les variables suivantes peuvent être utilisées pour le pied de page :",
+ "domain_footer_info": "Les pieds de page du domaine sont ajoutés à tous les courriels sortants associés à une adresse au sein de ce domaine.
Les variables suivantes peuvent être utilisées pour le pied de page :",
"domain_footer_plain": "Pied de page",
"app_passwd_protocols": "Protocoles autorisés pour le mot de passe d'application",
"created_on": "Créé le",
@@ -663,7 +680,9 @@
"mailbox_rename_agree": "J'ai fait une sauvegarde.",
"mailbox_rename_warning": "IMPORTANT ! Faites une sauvegarde avant de renommer la boîte de réception.",
"mailbox_rename_alias": "Créer un alias automatiquement",
- "sogo_access": "Autoriser la connexion directe à SOGo"
+ "sogo_access": "Autoriser la connexion directe à SOGo",
+ "pushover": "Pushover",
+ "pushover_sound": "Son"
},
"footer": {
"cancel": "Annuler",
@@ -677,7 +696,8 @@
"restart_container_info": "Important : Un redémarrage en douceur peut prendre un certain temps, veuillez attendre qu’il soit terminé.",
"restart_now": "Redémarrer maintenant",
"restarting_container": "Redémarrage du conteneur, cela peut prendre un certain temps",
- "nothing_selected": "Rien n'est sélectionné"
+ "nothing_selected": "Rien n'est sélectionné",
+ "hibp_check": "Vérifier avec haveibeenpwned.com"
},
"header": {
"administration": "Configuration & détails",
@@ -688,7 +708,8 @@
"quarantine": "Quarantaine",
"restart_netfilter": "Redémarrer Netfilter",
"restart_sogo": "Redémarrer SOGo",
- "user_settings": "Paramètres utilisateur"
+ "user_settings": "Paramètres utilisateur",
+ "mailcow_system": "Système"
},
"info": {
"awaiting_tfa_confirmation": "En attente de la confirmation de TFA",
@@ -779,7 +800,7 @@
"hourly": "Toutes les heures",
"in_use": "Utilisé (%)",
"inactive": "Inactif",
- "insert_preset": "Insérer un exemple de préréglage \"%s\"",
+ "insert_preset": "Insérer un exemple de préréglage « %s »",
"kind": "Type",
"last_mail_login": "Dernière connexion mail",
"last_modified": "Dernière modification",
@@ -831,7 +852,7 @@
"sieve_preset_5": "Répondeur auto (vacances)",
"sieve_preset_6": "Rejeter le courrier avec réponse",
"sieve_preset_7": "Rediriger et garder/déposer",
- "sieve_preset_8": "Rediriger les courriels d'un expéditeur spécifique, les marquer comme lus et les classer dans des sous-dossiers.",
+ "sieve_preset_8": "Rediriger les courriels d'un expéditeur spécifique, les marquer comme lus et les classer dans des sous-dossiers",
"sieve_preset_header": "Voir les exemples de préréglages ci-dessous. Pour plus de détails, voir Wikipédia.",
"sogo_visible": "Alias visible dans SOGo",
"sogo_visible_n": "Masquer alias dans SOGo",
@@ -871,7 +892,20 @@
"all_domains": "Tous les domaines",
"syncjob_EXIT_OVERQUOTA": "Quota dépassé de la boîte de réception cible",
"domain_templates": "Modèles de domaine",
- "syncjob_last_run_result": "Résultat de la dernière exécution"
+ "syncjob_last_run_result": "Résultat de la dernière exécution",
+ "sender": "Expéditeur",
+ "add_template": "Ajouter un modèle",
+ "syncjob_EX_OK": "Succès",
+ "syncjob_EXIT_CONNECTION_FAILURE": "Problème de connexion",
+ "syncjob_EXIT_TLS_FAILURE": "Problème avec le chiffrement de la connexion",
+ "syncjob_EXIT_AUTHENTICATION_FAILURE": "Problème d'authentification",
+ "syncjob_EXIT_CONNECTION_FAILURE_HOST1": "Impossible de se connecter au serveur distant",
+ "syncjob_EXIT_AUTHENTICATION_FAILURE_USER1": "Utilisateur ou mot de passe erroné",
+ "templates": "Modèles",
+ "template": "Modèle",
+ "syncjob_check_log": "Vérifier le journal",
+ "recipient": "Destinataire",
+ "open_logs": "Afficher les journaux"
},
"oauth2": {
"access_denied": "Veuillez vous connecter en tant que propriétaire de la boîte de réception pour accorder l’accès via Oauth2.",
@@ -889,9 +923,9 @@
"confirm": "Confirmer",
"confirm_delete": "Confirmer la suppression de cet élément.",
"danger": "Danger",
- "deliver_inbox": "Envoyer dans la boîte de reception",
- "disabled_by_config": "La configuration actuelle du système désactive la fonctionnalité de quarantaine. Veuillez définir « retentions par boîte » et une « taille maximale » pour les éléments en quarantaine.",
- "settings_info": "Quantité maximale d'éléments à mettre en quarantaine : %s
Taille maximale des courriels : %s MiB",
+ "deliver_inbox": "Envoyer dans la boîte de réception",
+ "disabled_by_config": "La configuration actuelle du système désactive la fonctionnalité de quarantaine. Veuillez définir « retentions par boîte » et une « taille maximale » pour les éléments en quarantaine.",
+ "settings_info": "Quantité maximale d'éléments à mettre en quarantaine : %s
Taille maximale des courriels : %s Mio",
"download_eml": "Télécharger (.eml)",
"empty": "Pas de résultat",
"high_danger": "Haut",
@@ -904,7 +938,7 @@
"notified": "Notifié",
"qhandler_success": "Demande envoyée avec succès au système. Vous pouvez maintenant fermer la fenêtre.",
"qid": "Rspamd QID",
- "qinfo": "Le système de quarantaine enregistrera le courrier rejeté dans la base de données (l'expéditeur n'aura pas l'impression d'un courrier remis) ainsi que le courrier, remis sous forme de copie dans le dossier indésirable d'une boîte de réception.\n
« Apprendre comme spam et supprimer » apprendra un message comme spam via le théorème Bayésien calculera également des hachages flous pour refuser des messages similaires à l'avenir.\n
Veuillez noter que l'apprentissage de plusieurs messages peut prendre du temps, selon votre système.
Les éléments figurant sur la liste noire sont exclus de la quarantaine.",
+ "qinfo": "Le système de quarantaine enregistrera le courrier rejeté dans la base de données (l'expéditeur n'aura pas l'impression d'un courrier remis) ainsi que le courrier, remis sous forme de copie dans le dossier indésirable d'une boîte de réception.\n
« Apprendre comme spam et supprimer » apprendra un message comme spam via le théorème Bayésien et calculera également des hachages flous pour refuser des messages similaires à l'avenir.\n
Veuillez noter que l'apprentissage de plusieurs messages peut prendre du temps, selon votre système.
Les éléments figurant sur la liste noire sont exclus de la quarantaine.",
"qitem": "Élément de quarantaine",
"quarantine": "Quarantaine",
"quick_actions": "Actions",
@@ -920,7 +954,7 @@
"rewrite_subject": "Réécrire le sujet",
"rspamd_result": "Résultat Rspamd",
"sender": "Expéditeur (SMTP)",
- "sender_header": "Expéditeur (\"From\" header)",
+ "sender_header": "Expéditeur (« From » header)",
"type": "Type",
"quick_release_link": "Ouvrir le lien de dégagement rapide",
"quick_delete_link": "Ouvrir le lien de suppression rapide",
@@ -938,14 +972,18 @@
"queue": {
"queue_manager": "Gestion de la file d'attente",
"hold_mail": "Garder",
- "legend": "Fonctions d'action de la file d'attente du courrier :",
+ "legend": "Fonctions d'action de la file d'attente du courrier :",
"info": "La file d'attente contient tous les courriels en attente de livraison. Si un courriel reste longtemps dans la file d'attente, il est automatiquement supprimé par le système.
Le message d'erreur du courriel concerné indique pourquoi le courriel n'a pas pu être distribué.",
"deliver_mail_legend": "Tentatives de réexpédition des courriers sélectionnés.",
"hold_mail_legend": "Met en attente les courriers sélectionnés. (Empêche les tentatives de distribution ultérieures)",
"unban": "file d'attente d'unban",
"unhold_mail": "Libérer",
"unhold_mail_legend": "Libère les courriers sélectionnés pour la distribution. (Nécessite une mise en attente préalable)",
- "show_message": "Afficher le message"
+ "show_message": "Afficher le message",
+ "delete": "Tout supprimer",
+ "flush": "Vider la file d'attente",
+ "ays": "Veuillez confirmer que vous souhaitez supprimer tous les éléments de la file d'attente actuelle.",
+ "deliver_mail": "Délivrer"
},
"start": {
"help": "Afficher/masquer le panneau d’aide",
@@ -973,9 +1011,9 @@
"bcc_saved": "Saisie de carte BCC enregistrée",
"db_init_complete": "Initialisation de la base de données terminée",
"delete_filter": "ID des filtres supprimés %s",
- "delete_filters": "Filtres supprimés : %s",
- "deleted_syncjob": "ID de la tâche de synchronisation supprimée : %s",
- "deleted_syncjobs": "Tâche de synchronisation supprimée : %s",
+ "delete_filters": "Filtres supprimés : %s",
+ "deleted_syncjob": "ID de la tâche de synchronisation supprimée : %s",
+ "deleted_syncjobs": "Tâche de synchronisation supprimée : %s",
"dkim_added": "La clé DKIM %s a été enregistrée",
"dkim_duplicated": "La clé DKIM pour le domaine %s a été copiée vers %s",
"dkim_removed": "La clé DKIM %s a été supprimée",
@@ -1008,7 +1046,7 @@
"qlearn_spam": "Le message ID %s a été appris comme spam et supprimé",
"queue_command_success": "Queue de commande terminée avec succès",
"recipient_map_entry_deleted": "La carte du destinataire ID %s a été effacée",
- "recipient_map_entry_saved": "L'entrée de la carte du bénéficiaire \"%s\" a été enregistrée",
+ "recipient_map_entry_saved": "L'entrée de la carte du destinataire « %s » a été enregistrée",
"relayhost_added": "L'entrée de la carte %s a été ajoutée",
"relayhost_removed": "L'entrée de la carte %s a été supprimée",
"reset_main_logo": "Réinitialisation du logo par défaut",
@@ -1022,7 +1060,7 @@
"settings_map_removed": "Suppression de la carte des paramètres ID %s",
"sogo_profile_reset": "Le profil SOGo profile pour l'utilisateur %s est remis à zéro",
"tls_policy_map_entry_deleted": "La carte de stratégie TLS ID %s a été supprimée",
- "tls_policy_map_entry_saved": "La carte de stratégie TLS ID \"%s\" a été enregistrée",
+ "tls_policy_map_entry_saved": "La carte de stratégie TLS ID « %s » a été enregistrée",
"ui_texts": "Enregistrement des modifications apportées aux textes de l’interface utilisateur",
"upload_success": "Fichier téléchargé avec succès",
"verified_totp_login": "Authentification TOTP vérifiée",
@@ -1038,7 +1076,9 @@
"ip_check_opt_in_modified": "Le contrôle de l'IP a été enregistré avec succès",
"password_changed_success": "Le mot de passe a été modifié avec succès",
"recovery_email_sent": "Email de réinitialisation envoyé à %s",
- "mailbox_renamed": "La boîte de réception a été renommée de %s à %s"
+ "mailbox_renamed": "La boîte de réception a été renommée de %s à %s",
+ "template_modified": "Les modifications au modèle %s ont été enregistrées",
+ "password_policy_saved": "La politique de mot de passe a été enregistrée avec succès"
},
"tfa": {
"api_register": "%s utilise l'API Yubico Cloud. Veuillez obtenir une clé API pour votre clé ici",
@@ -1059,7 +1099,7 @@
"start_webauthn_validation": "Début de la validation",
"tfa": "Authentification à deux facteurs",
"tfa_token_invalid": "Token TFA invalide",
- "totp": "OTP (One Time Password = Mot de passe à usage unique : Google Authenticator, Authy, etc.)",
+ "totp": "OTP (One Time Password = Mot de passe à usage unique : Google Authenticator, Authy, etc.)",
"webauthn": "Authentification WebAuthn",
"waiting_usb_auth": "En attente d’un périphérique USB…
S’il vous plaît appuyez maintenant sur le bouton de votre périphérique USB WebAuthn.",
"waiting_usb_register": "En attente d’un périphérique USB…
Veuillez entrer votre mot de passe ci-dessus et confirmer votre inscription WebAuthn en appuyant sur le bouton de votre périphérique USB WebAuthn.",
@@ -1098,7 +1138,7 @@
"alias_valid_until": "Valide jusque",
"aliases_also_send_as": "Aussi autorisé à envoyer en tant qu’utilisateur",
"aliases_send_as_all": "Ne pas vérifier l’accès de l’expéditeur pour les domaines suivants et leurs alias",
- "app_hint": "Les mots de passe d’application sont des mots de passe alternatifs pour votre connexion IMAP, SMTP, Caldav, Carddav et EAS. Le nom d’utilisateur reste inchangé.
SOGo n'est pas disponible au travers des mots de passe d'application.",
+ "app_hint": "Les mots de passe d’application sont des mots de passe alternatifs pour votre connexion IMAP, SMTP, CalDAV, CardDAV et EAS. Le nom d’utilisateur reste inchangé.
Le webmail SOGo n'est pas disponible au travers des mots de passe d'application.",
"app_name": "Nom d'application",
"app_passwds": "Mots de passe d'applications",
"apple_connection_profile": "Profil de connexion Apple",
@@ -1114,7 +1154,7 @@
"direct_aliases": "Adresses d'alias directes",
"direct_aliases_desc": "Les adresses d’alias directes sont affectées par le filtre anti-spam et les paramètres de politique TLS.",
"eas_reset": "Réinitialiser le cache de l’appareil ActiveSync",
- "eas_reset_help": "Dans de nombreux cas, une réinitialisation du cache de l’appareil aidera à récupérer un profil ActiveSync cassé.
Attention : Tous les éléments seront de nouveau téléchargés !",
+ "eas_reset_help": "Dans de nombreux cas, une réinitialisation du cache de l’appareil aidera à récupérer un profil ActiveSync cassé.
Attention : Tous les éléments seront de nouveau téléchargés !",
"eas_reset_now": "Réinitialiser maintenant",
"edit": "Éditer",
"email": "Courriel",
@@ -1147,7 +1187,7 @@
"pushover_evaluate_x_prio": "Acheminement du courrier hautement prioritaire [X-Priority: 1]",
"pushover_info": "Les paramètres de notification push s’appliqueront à tout le courrier propre (non spam) livré à %s y compris les alias (partagés, non partagés, étiquetés).",
"pushover_only_x_prio": "Ne tenir compte que du courrier hautement prioritaire [X-Priority: 1]",
- "pushover_sender_array": "Tenir compte des adresses de courriel suivantes de l’expéditeur : (comma-separated)",
+ "pushover_sender_array": "Tenir compte des adresses de courriel de l’expéditeur suivantes : (séparées par des virgules)",
"pushover_sender_regex": "Apparier les expéditeurs par le regex suivant",
"pushover_text": "Texte de notification",
"pushover_title": "Titre de la notification",
@@ -1158,8 +1198,8 @@
"q_reject": "Rejeté",
"quarantine_notification": "Avis de quarantaine",
"quarantine_category": "Catégorie de la notification de quarantaine",
- "quarantine_notification_info": "Une fois qu’un avis a été envoyé, les articles seront marqués comme « notifiés » et aucune autre notification ne sera envoyée pour ce point particulier.",
- "quarantine_category_info": "La catégorie de notification « Rejeté » inclut le courrier rejeté, tandis que « Dossier indésirable » informera un utilisateur des courriels placés dans le dossier indésirable.",
+ "quarantine_notification_info": "Une fois qu’un avis a été envoyé, les articles seront marqués comme « notifiés » et aucune autre notification ne sera envoyée pour ce point particulier.",
+ "quarantine_category_info": "La catégorie de notification « Rejeté » inclut le courrier rejeté, tandis que « Dossier indésirable » informera un utilisateur des courriels placés dans le dossier indésirable.",
"remove": "Enlever",
"running": "En fonctionnement",
"save": "Enregistrer les changements",
@@ -1176,11 +1216,11 @@
"spamfilter": "Filtre de spam",
"spamfilter_behavior": "Note",
"spamfilter_bl": "Liste noire (BlackList)",
- "spamfilter_bl_desc": "Les adresses de courriel sur liste noire qui doivent toujours être classées comme des pourriels et rejetées. Les messages rejetés ne seront pas copiés dans la quarantaine. Des caractères génériques peuvent être utilisés. Un filtre n’est appliqué qu’aux alias directs (alias avec une seule boîte de réception cible), à l’exclusion des alias attrape-tout et d’une boîte de réception elle-même.",
+ "spamfilter_bl_desc": "Les adresses de courriel sur liste noire qui doivent toujours être classées comme des pourriels et rejetées. Les messages rejetés ne seront pas copiés dans la quarantaine. Des caractères génériques peuvent être utilisés. Un filtre n’est appliqué qu’aux alias directs (alias avec une seule boîte de réception cible), à l’exclusion des alias attrape-tout et d’une boîte de réception elle-même.",
"spamfilter_default_score": "Valeurs par défaut",
- "spamfilter_green": "Vert : ce message n'est pas un spam",
- "spamfilter_hint": "La première valeur indique un « faible score de spam », la seconde représente un « haut score de spam ».",
- "spamfilter_red": "Rouge : Ce message est un spam et sera rejeté par le serveur",
+ "spamfilter_green": "Vert : ce message n'est pas un spam",
+ "spamfilter_hint": "La première valeur indique un « faible score de spam », la seconde représente un « haut score de spam ».",
+ "spamfilter_red": "Rouge : Ce message est un spam et sera rejeté par le serveur",
"spamfilter_table_action": "Action",
"spamfilter_table_add": "Ajouter un élément",
"spamfilter_table_domain_policy": "n/a (politique de domaine)",
@@ -1189,12 +1229,12 @@
"spamfilter_table_rule": "Règle",
"spamfilter_wl": "Liste blanche (WhiteList)",
"spamfilter_wl_desc": "La liste blanche est programmée pour ne jamais classer comme spam les adresses de courriel qu'elle contient. Des caractères génériques peuvent être utilisés. Un filtre n’est appliqué qu’aux alias directs (alias avec une seule boîte de réception cible), à l’exclusion des alias attrape-tout et d’une boîte de réception.",
- "spamfilter_yellow": "Jaune : ce message est peut être un spam, il sera étiqueté comme spam et déplacé vers votre dossier Pourriel",
+ "spamfilter_yellow": "Jaune : ce message est peut-être un spam, il sera étiqueté comme spam et déplacé vers votre dossier Pourriel",
"status": "Statut",
"sync_jobs": "Tâches de synchronisation",
"tag_handling": "Régler la manipulation du courrier étiqueté",
- "tag_help_example": "Exemple pour une adresse de courriel étiquetée : me+Facebook@example.org",
- "tag_help_explain": "Dans un sous-dossier : un nouveau sous-dossier nommé selon l'étiquette sera créé sous INBOX (\"INBOX/Facebook\").
\nDans le sujet : le nom des balises sera ajouté au début du sujet de l'e-mail, exemple : \"[Facebook] My News\".",
+ "tag_help_example": "Exemple pour une adresse de courriel étiquetée : me+Facebook@example.org",
+ "tag_help_explain": "Dans un sous-dossier : un nouveau sous-dossier nommé selon l'étiquette sera créé sous INBOX (« INBOX/Facebook »).
\nDans le sujet : le nom des balises sera ajouté au début du sujet de l'e-mail, exemple : « [Facebook] My News ».",
"tag_in_none": "Ne rien faire",
"tag_in_subfolder": "Dans un sous dossier",
"tag_in_subject": "Dans le sujet",
@@ -1217,7 +1257,7 @@
"with_app_password": "avec le mot de passe de l'application",
"apple_connection_profile_with_app_password": "Un nouveau mot de passe est généré et ajouté au profil, de sorte qu'aucun mot de passe ne doit être saisi lors de la configuration de votre appareil. Ne partagez pas le fichier car il vous donne un accès complet à votre boîte de réception.",
"attribute": "Attribut",
- "direct_protocol_access": "Cet utilisateur de la boîte aux lettres dispose d'un accès externe direct aux protocoles et applications suivants. Votre administrateur contrôle ce paramètre. Il est possible de créer des mots de passe d'application pour accorder l'accès à des protocoles et des applications individuels.
Le bouton « Connexion au webmail » permet une connexion unique à SOGo et est toujours disponible.",
+ "direct_protocol_access": "Cet utilisateur de la boîte aux lettres dispose d'un accès externe direct aux protocoles et applications suivants. Votre administrateur contrôle ce paramètre. Il est possible de créer des mots de passe d'application pour accorder l'accès à des protocoles et des applications individuels.
Le bouton « Connexion au webmail » permet une connexion unique à SOGo et est toujours disponible.",
"open_webmail_sso": "Connexion au webmail",
"recent_successful_connections": "Voir les connexions réussies",
"syncjob_EXIT_TLS_FAILURE": "Problème de connexion chiffrée",
@@ -1240,7 +1280,14 @@
"password_reset_info": "Si aucun email pour la récupération du mot de passe n'est fourni, cette fonction ne peut pas être utilisée.",
"pw_recovery_email": "Email de récupération pour son mot de passe",
"month": "mois",
- "from": "de"
+ "from": "de",
+ "empty": "Aucun résultat",
+ "fido2_webauthn": "FIDO2/WebAuthn",
+ "last_pw_change": "Dernier changement de mot de passe",
+ "open_logs": "Afficher les journaux",
+ "pushover_sound": "Son",
+ "mailbox_general": "Général",
+ "mailbox_settings": "Paramètres"
},
"warning": {
"cannot_delete_self": "Impossible de supprimer l’utilisateur connecté",
@@ -1248,11 +1295,11 @@
"dovecot_restart_failed": "Dovecot n’a pas pu redémarrer, veuillez vérifier les journaux",
"fuzzy_learn_error": "Erreur d’apprentissage du hachage flou : %s",
"hash_not_found": "Hachage non trouvé ou déjà supprimé",
- "ip_invalid": "IP non valide ignorée : %s",
+ "ip_invalid": "IP non valide ignorée : %s",
"no_active_admin": "Impossible de désactiver le dernier administrateur actif",
- "quota_exceeded_scope": "Dépassement du quota de domaine : Seules des boîtes de réception illimitées peuvent être créées dans ce domaine.",
- "session_token": "Jeton de formulaire invalide : Jeton différent",
- "session_ua": "Jeton de formulaire invalide : erreur de validation User-Agent",
+ "quota_exceeded_scope": "Dépassement du quota de domaine : Seules des boîtes de réception illimitées peuvent être créées dans ce domaine.",
+ "session_token": "Jeton de formulaire invalide : Jeton différent",
+ "session_ua": "Jeton de formulaire invalide : erreur de validation User-Agent",
"is_not_primary_alias": "Alias non primaire ignoré %s"
},
"datatables": {
@@ -1261,7 +1308,9 @@
"thousands": ",",
"paginate": {
"first": "Premier",
- "last": "Dernier"
+ "last": "Dernier",
+ "next": "Suivant",
+ "previous": "Précédent"
},
"aria": {
"sortAscending": ": activer pour trier les colonnes en ordre croissant",
@@ -1274,9 +1323,15 @@
"processing": "Veuillez patienter…",
"collapse_all": "Tout réduire",
"info": "Affichage de _START_ à _END_ sur _TOTAL_ entrée(s)",
- "search": "Rechercher :"
+ "search": "Rechercher :",
+ "emptyTable": "Aucune donnée présente dans la table",
+ "zeroRecords": "Aucun enregistrement correspondant trouvé"
},
"ratelimit": {
- "disabled": "Désactivé"
+ "disabled": "Désactivé",
+ "second": "msgs / seconde",
+ "minute": "msgs / minute",
+ "hour": "msgs / heure",
+ "day": "msgs / jour"
}
}
From 40a8bc808ab72ddcef36f382dabb148b06260751 Mon Sep 17 00:00:00 2001
From: milkmaker
Date: Wed, 1 Jan 2025 03:26:18 +0100
Subject: [PATCH 37/52] update postscreen_access.cidr (#6232)
---
data/conf/postfix/postscreen_access.cidr | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/data/conf/postfix/postscreen_access.cidr b/data/conf/postfix/postscreen_access.cidr
index 1dbe94773..741b32298 100644
--- a/data/conf/postfix/postscreen_access.cidr
+++ b/data/conf/postfix/postscreen_access.cidr
@@ -1,6 +1,6 @@
-# Whitelist generated by Postwhite v3.4 on Sun Dec 1 00:21:36 UTC 2024
+# Whitelist generated by Postwhite v3.4 on Wed Jan 1 00:18:52 UTC 2025
# https://github.com/stevejenkins/postwhite/
-# 1971 total rules
+# 2014 total rules
2a00:1450:4000::/36 permit
2a01:111:f400::/48 permit
2a01:111:f403:8000::/50 permit
@@ -19,6 +19,10 @@
8.20.114.31 permit
8.25.194.0/23 permit
8.25.196.0/23 permit
+8.39.54.0/23 permit
+8.39.54.250/31 permit
+8.40.222.0/23 permit
+8.40.222.250/31 permit
10.162.0.0/16 permit
12.130.86.238 permit
13.110.208.0/21 permit
@@ -1472,6 +1476,9 @@
163.114.135.16 permit
164.152.23.32 permit
164.177.132.168/30 permit
+165.173.128.0/24 permit
+165.173.180.250/31 permit
+165.173.182.250/31 permit
166.78.68.0/22 permit
166.78.68.221 permit
166.78.69.169 permit
@@ -1500,6 +1507,12 @@
168.245.12.252 permit
168.245.46.9 permit
168.245.127.231 permit
+169.148.129.0/24 permit
+169.148.131.0/24 permit
+169.148.142.10 permit
+169.148.144.0/25 permit
+169.148.144.10 permit
+169.148.146.0/23 permit
170.10.128.0/24 permit
170.10.129.0/24 permit
170.10.132.56/29 permit
@@ -1959,6 +1972,9 @@
2603:1030:20e:3::23c permit
2603:1030:b:3::152 permit
2603:1030:c02:8::14 permit
+2607:13c0:0001:0000:0000:0000:0000:7000/116 permit
+2607:13c0:0002:0000:0000:0000:0000:1000/116 permit
+2607:13c0:0004:0000:0000:0000:0000:0000/116 permit
2607:f8b0:4000::/36 permit
2620:109:c003:104::/64 permit
2620:109:c003:104::215 permit
From 10328981b6abe2f65deecd7ba6f2eb7d284c6014 Mon Sep 17 00:00:00 2001
From: milkmaker
Date: Sun, 5 Jan 2025 15:25:45 +0100
Subject: [PATCH 38/52] Translations update from Weblate (#6235)
* [Web] Updated lang.fr-fr.json
Co-authored-by: Neuronnexion
* [Web] Updated lang.zh-cn.json
Co-authored-by: Easton Man
---------
Co-authored-by: Neuronnexion
Co-authored-by: Easton Man
---
data/web/lang/lang.fr-fr.json | 2 +-
data/web/lang/lang.zh-cn.json | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/data/web/lang/lang.fr-fr.json b/data/web/lang/lang.fr-fr.json
index 0e250b0ae..61739bf85 100644
--- a/data/web/lang/lang.fr-fr.json
+++ b/data/web/lang/lang.fr-fr.json
@@ -805,7 +805,7 @@
"last_mail_login": "Dernière connexion mail",
"last_modified": "Dernière modification",
"last_run": "Dernière exécution",
- "last_run_reset": "Calendrier suivant",
+ "last_run_reset": "Exécuter maintenant",
"mailbox": "Boîte de réception",
"mailbox_defquota": "Taille de boîte de réception par défaut",
"mailbox_quota": "Taille max. d’une boîte de réception",
diff --git a/data/web/lang/lang.zh-cn.json b/data/web/lang/lang.zh-cn.json
index cf0c22b61..7e26422cc 100644
--- a/data/web/lang/lang.zh-cn.json
+++ b/data/web/lang/lang.zh-cn.json
@@ -205,7 +205,7 @@
"in_use_by": "使用者",
"inactive": "禁用",
"include_exclude": "包括/排除",
- "include_exclude_info": "默认 - 没有选择时默认包括所有邮箱",
+ "include_exclude_info": "默认 - 没有选择时默认包括所有邮箱",
"includes": "包括这些收件人",
"is_mx_based": "基于 MX 记录",
"last_applied": "最后应用的条目",
@@ -339,7 +339,7 @@
"yes": "✓",
"options": "选项",
"f2b_max_ban_time": "最长封禁时间(秒)",
- "copy_to_clipboard": "复制到粘贴板",
+ "copy_to_clipboard": "已复制到粘贴板!",
"reset_password_vars": "{{link}} 生成的密码重置链接
{{username}} 要求重置密码的使用者的邮箱名称
{{username2}} 复原邮箱名称
{{date}} 要求重置密码之日期
{{token_lifetime}} 令牌(token)过期时间(以分钟计)
{{hostname}} mailcow 主机名",
"logo_normal_label": "正常",
"f2b_manage_external_info": "Fail2Ban 还会持续维护封禁列表,但不会主动设置规则阻挡流量。请使用以下生成的封禁列表在外部阻止流量。",
@@ -584,7 +584,7 @@
"force_pw_update_info": "此用户只能登录到 %s。",
"full_name": "全名",
"gal": "全球地址簿",
- "gal_info": "全球地址簿包含了域名下的所有对象,并且此行为不能被用户更改。如果关闭,用户的 \"空闲/繁忙\" 的信息将不能在 SOGo 中显示。 重启 SOGo 服务以应用更改。",
+ "gal_info": "全球地址簿(GAL)包含了域名下的所有对象,并且此行为不能被用户更改。如果关闭,用户的 \"空闲/繁忙\" 的信息将不能在 SOGo 中显示。 重启 SOGo 服务以应用更改。",
"generate": "生成",
"grant_types": "授权类型",
"hostname": "主机名",
From 69f6a82905e98ad23210f4d8a0dd70ce6d5c7d1b Mon Sep 17 00:00:00 2001
From: milkmaker
Date: Thu, 9 Jan 2025 06:51:42 +0100
Subject: [PATCH 39/52] [Web] Updated lang.fr-fr.json (#6238)
Co-authored-by: Neuronnexion
---
data/web/lang/lang.fr-fr.json | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/data/web/lang/lang.fr-fr.json b/data/web/lang/lang.fr-fr.json
index 61739bf85..68226c1fd 100644
--- a/data/web/lang/lang.fr-fr.json
+++ b/data/web/lang/lang.fr-fr.json
@@ -56,7 +56,7 @@
"disable_login": "Désactiver l'authentification (les courriels entrants resteront acceptés)",
"domain": "Domaine",
"domain_matches_hostname": "Le domaine %s correspond à la machine (hostname)",
- "domain_quota_m": "Quota total du domaine (Mo)",
+ "domain_quota_m": "Quota total du domaine (Mio)",
"enc_method": "Méthode de chiffrement",
"exclude": "Exclure des objets (expression régulière - regex)",
"full_name": "Nom complet",
@@ -70,7 +70,7 @@
"inactive": "Inactif",
"kind": "Type",
"mailbox_quota_def": "Quota boîte de réception par défaut",
- "mailbox_quota_m": "Quota max par boîte de réception (Mo)",
+ "mailbox_quota_m": "Quota max par boîte de réception (Mio)",
"mailbox_username": "Identifiant (partie gauche d'une adresse de courriel)",
"max_aliases": "Nombre maximal d'alias",
"max_mailboxes": "Nombre maximal de boîtes de réception",
@@ -83,7 +83,7 @@
"post_domain_add": "Le conteneur SOGo, « sogo-mailcow », doit être redémarré après l'ajout d'un nouveau domaine !
De plus, la configuration DNS doit être révisée. Lorsque la configuration DNS est approuvée, redémarrer « acme-mailcow » pour générer automatiquement les certificats pour votre nouveau domaine (autoconfig.<domain>, autodiscover.<domain>).
Cette étape est optionnelle et sera réessayée toutes les 24 heures.",
"private_comment": "Commentaire privé",
"public_comment": "Commentaire public",
- "quota_mb": "Quota (Mo)",
+ "quota_mb": "Quota (Mio)",
"relay_all": "Relayer tous les destinataires",
"relay_all_info": "↪ Si vous choisissez de ne pas relayer tous les destinataires, vous devez ajouter une boîte de réception (« aveugle ») pour chaque destinataire simple qui doit être relayé.",
"relay_domain": "Relayer ce domaine",
@@ -236,7 +236,7 @@
"quarantine_bcc": "Envoyer une copie de toutes les notifications (BCC) à ce destinataire :
Laisser vide pour le désactiver. Courrier non signé et non coché. Doit être livré en interne seulement.",
"quarantine_exclude_domains": "Exclure les domaines et les alias de domaine",
"quarantine_max_age": "Âge maximun en jour(s)
La valeur doit être égale ou supérieure à 1 jour.",
- "quarantine_max_size": "Taille maximum en Mo (les éléments plus grands sont mis au rebut) :
0 ne signifie pas illimité.",
+ "quarantine_max_size": "Taille maximum en Mio (les éléments plus grands sont mis au rebut) :
0 ne signifie pas illimité.",
"quarantine_max_score": "Ignorer la notification si le score de spam est au dessus de cette valeur :
Par défaut : 9999.0",
"quarantine_notification_html": "Modèle de courriel de notification :
Laisser vide pour restaurer le modèle par défaut.",
"quarantine_notification_sender": "Notification par courriel de l’expéditeur",
@@ -384,7 +384,7 @@
"domain_invalid": "Le nom de domaine est vide ou non valide",
"domain_not_empty": "Impossible de supprimer le domaine non vide %s",
"domain_not_found": "Le domaine %s est introuvable",
- "domain_quota_m_in_use": "Le quota de domaine doit être supérieur ou égal à %s Mo",
+ "domain_quota_m_in_use": "Le quota de domaine doit être supérieur ou égal à %s Mio",
"extra_acl_invalid": "L'adresse de l’expéditeur externe « %s » est non valide",
"extra_acl_invalid_domain": "L'expéditeur externe « %s » utilise un domaine non valide",
"file_open_error": "Le fichier ne peut pas être ouvert pour l'écriture",
@@ -416,7 +416,7 @@
"login_failed": "La connexion a échoué",
"mailbox_defquota_exceeds_mailbox_maxquota": "Le quota par défaut dépasse la limite maximale du quota",
"mailbox_invalid": "Le nom de la boîte de réception n'est pas valide",
- "mailbox_quota_exceeded": "Le quota dépasse la limite du domaine (max. %d Mo)",
+ "mailbox_quota_exceeded": "Le quota dépasse la limite du domaine (max. %d Mio)",
"mailbox_quota_exceeds_domain_quota": "Le quota maximal dépasse la limite du quota de domaine",
"mailbox_quota_left_exceeded": "Espace libre insuffisant (espace libre : %d Mio)",
"mailboxes_in_use": "Le max. des boîtes de réception doit être supérieur ou égal à %d",
@@ -424,7 +424,7 @@
"map_content_empty": "Le contenu de la carte ne peut pas être vide",
"max_alias_exceeded": "Le nombre max. d'alias est dépassé",
"max_mailbox_exceeded": "Le nombre max. de boîte de réception est dépassé (%d of %d)",
- "max_quota_in_use": "Le quota de la boîte de réception doit être supérieur ou égal à %d Mo",
+ "max_quota_in_use": "Le quota de la boîte de réception doit être supérieur ou égal à %d Mio",
"maxquota_empty": "Le quota maximum par boîte de réception ne doit pas être de 0.",
"mysql_error": "Erreur MySQL : %s",
"nginx_reload_failed": "Le rechargement de Nginx a échoué : %s",
@@ -593,7 +593,7 @@
"mailbox_quota_def": "Quota par défaut de la boîte de réception",
"max_aliases": "Nombre max. d'alias",
"max_mailboxes": "Nombre max. de boîte de réception possibles",
- "max_quota": "Quota max. par boîte de réception (Mo)",
+ "max_quota": "Quota max. par boîte de réception (Mio)",
"maxage": "Âge maximal en jours des messages qui seront consultés à distance
(0 = ignorer la durée)",
"maxbytespersecond": "Octets max. par seconde
(0 = pas de limite)",
"mbox_rl_info": "Cette limite d'envoi est appliquée au nom de connexion SASL, elle correspond à toute adresse « from » utilisée par l’utilisateur connecté. Une limite d'envoi pour les boîtes de réception remplace une limite d'envoi pour l’ensemble du domaine.",
@@ -614,7 +614,7 @@
"pushover_title": "Titre de la notification",
"pushover_vars": "Lorsque aucun filtre d’expéditeur n’est défini, tous les messages seront considérés.
Les filtres Regex ainsi que les vérifications exactes de l’expéditeur peuvent être définis individuellement et seront considérés de façon séquentielle. Ils ne dépendent pas les uns des autres.
Variables utilisables pour le texte et le titre (veuillez prendre note des politiques de protection des données)",
"pushover_verify": "Vérifier les informations d'identification",
- "quota_mb": "Quota (Mo)",
+ "quota_mb": "Quota (Mio)",
"ratelimit": "Limite d'envoi",
"redirect_uri": "URL de redirection/callback",
"relay_all": "Relayer tous les destinataires",
From abd789f629a88e5cf7e5eb45f2c19224e91e2f25 Mon Sep 17 00:00:00 2001
From: FreddleSpl0it
Date: Tue, 14 Jan 2025 11:18:20 +0100
Subject: [PATCH 40/52] [Web] Escape mailbox name before querying aliases
---
data/web/inc/functions.inc.php | 4 ++--
data/web/inc/functions.mailbox.inc.php | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php
index cfe507549..7efbee166 100644
--- a/data/web/inc/functions.inc.php
+++ b/data/web/inc/functions.inc.php
@@ -1174,7 +1174,7 @@ function user_get_alias_details($username) {
AND `goto` != :username_goto2
AND `address` != :username_address");
$stmt->execute(array(
- ':username_goto' => '(^|,)'.$username.'($|,)',
+ ':username_goto' => '(^|,)'.preg_quote($username, '/').'($|,)',
':username_goto2' => $username,
':username_address' => $username
));
@@ -1222,7 +1222,7 @@ function user_get_alias_details($username) {
$data['aliases_send_as_all'] = $row['send_as'];
}
$stmt = $pdo->prepare("SELECT IFNULL(GROUP_CONCAT(`address` SEPARATOR ', '), '') as `address` FROM `alias` WHERE `goto` REGEXP :username AND `address` LIKE '@%';");
- $stmt->execute(array(':username' => '(^|,)'.$username.'($|,)'));
+ $stmt->execute(array(':username' => '(^|,)'.preg_quote($username, '/').'($|,)'));
$run = $stmt->fetchAll(PDO::FETCH_ASSOC);
while ($row = array_shift($run)) {
$data['is_catch_all'] = $row['address'];
diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php
index 6cc98e92e..1b6f9ae47 100644
--- a/data/web/inc/functions.mailbox.inc.php
+++ b/data/web/inc/functions.mailbox.inc.php
@@ -3768,7 +3768,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
$data['external_sender_aliases'] = array();
// Fixed addresses
$stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE `goto` REGEXP :goto AND `address` NOT LIKE '@%'");
- $stmt->execute(array(':goto' => '(^|,)'.$_data.'($|,)'));
+ $stmt->execute(array(':goto' => '(^|,)'.preg_quote($_data, '/').'($|,)'));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
while ($row = array_shift($rows)) {
$data['fixed_sender_aliases'][] = $row['address'];
@@ -5534,7 +5534,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
));
$stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias`
WHERE `goto` REGEXP :username");
- $stmt->execute(array(':username' => '(^|,)'.$username.'($|,)'));
+ $stmt->execute(array(':username' => '(^|,)'.preg_quote($username, '/').'($|,)'));
$GotoData = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($GotoData as $gotos) {
$goto_exploded = explode(',', $gotos['goto']);
From d280025b511bb27c2d45f04ff9201fe0ed359372 Mon Sep 17 00:00:00 2001
From: FreddleSpl0it
Date: Tue, 14 Jan 2025 11:30:41 +0100
Subject: [PATCH 41/52] [Web] Regenerate session_id on successful login
---
data/web/inc/triggers.inc.php | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/data/web/inc/triggers.inc.php b/data/web/inc/triggers.inc.php
index 360f57277..a49ba78c8 100644
--- a/data/web/inc/triggers.inc.php
+++ b/data/web/inc/triggers.inc.php
@@ -4,6 +4,7 @@ if (!empty($_GET['sso_token'])) {
$username = domain_admin_sso('check', $_GET['sso_token']);
if ($username !== false) {
+ session_regenerate_id();
$_SESSION['mailcow_cc_username'] = $username;
$_SESSION['mailcow_cc_role'] = 'domainadmin';
header('Location: /mailbox');
@@ -87,18 +88,21 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
$as = check_login($login_user, $_POST["pass_user"]);
if ($as == "admin") {
+ session_regenerate_id();
$_SESSION['mailcow_cc_username'] = $login_user;
$_SESSION['mailcow_cc_role'] = "admin";
header("Location: /debug");
die();
}
elseif ($as == "domainadmin") {
+ session_regenerate_id();
$_SESSION['mailcow_cc_username'] = $login_user;
$_SESSION['mailcow_cc_role'] = "domainadmin";
header("Location: /mailbox");
die();
}
elseif ($as == "user") {
+ session_regenerate_id();
$_SESSION['mailcow_cc_username'] = $login_user;
$_SESSION['mailcow_cc_role'] = "user";
$http_parameters = explode('&', $_SESSION['index_query_string']);
@@ -122,7 +126,9 @@ if (isset($_POST["login_user"]) && isset($_POST["pass_user"])) {
unset($_SESSION['pending_tfa_methods']);
unset($_SESSION['mailcow_cc_username']);
unset($_SESSION['mailcow_cc_role']);
- }
+ } else {
+ session_regenerate_id();
+ }
}
if (isset($_SESSION['mailcow_cc_role']) && (isset($_SESSION['acl']['login_as']) && $_SESSION['acl']['login_as'] == "1")) {
From 31e001ebee861c227cf24df9a14ca00871426816 Mon Sep 17 00:00:00 2001
From: DerLinkman
Date: Thu, 16 Jan 2025 11:37:15 +0100
Subject: [PATCH 42/52] flatcurve: change default amount of processes to 1
---
generate_config.sh | 2 +-
update.sh | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/generate_config.sh b/generate_config.sh
index 6e66c9197..3044ab8d7 100755
--- a/generate_config.sh
+++ b/generate_config.sh
@@ -394,7 +394,7 @@ FTS_HEAP=128
# Too many indexing processes can use a lot of CPU and Disk I/O.
# Please visit: https://doc.dovecot.org/configuration_manual/service_configuration/#indexer-worker for more informations
-FTS_PROCS=5
+FTS_PROCS=1
# Allow admins to log into SOGo as email user (without any password)
diff --git a/update.sh b/update.sh
index 6d9f8dd7e..1d0bfe8b6 100755
--- a/update.sh
+++ b/update.sh
@@ -466,7 +466,7 @@ adapt_new_options() {
echo '# Dovecot Indexing (FTS) Process maximum heap size in MB, there is no recommendation, please see Dovecot docs.' >> mailcow.conf
echo '# Flatcurve is used as FTS Engine. It is supposed to be pretty efficient in CPU and RAM consumption.' >> mailcow.conf
echo '# Please always monitor your Resource consumption!' >> mailcow.conf
- echo "FTS_HEAP=1024" >> mailcow.conf
+ echo "FTS_HEAP=128" >> mailcow.conf
fi
elif [[ ${option} == "SKIP_FTS" ]]; then
if ! grep -q ${option} mailcow.conf; then
@@ -481,7 +481,7 @@ adapt_new_options() {
echo '# Controls how many processes the Dovecot indexing process can spawn at max.' >> mailcow.conf
echo '# Too many indexing processes can use a lot of CPU and Disk I/O' >> mailcow.conf
echo '# Please visit: https://doc.dovecot.org/configuration_manual/service_configuration/#indexer-worker for more informations' >> mailcow.conf
- echo "FTS_PROCS=2" >> mailcow.conf
+ echo "FTS_PROCS=1" >> mailcow.conf
fi
elif [[ ${option} == "ENABLE_SSL_SNI" ]]; then
if ! grep -q ${option} mailcow.conf; then
From 08599c1960e663b211f82c5ef23240e118b91851 Mon Sep 17 00:00:00 2001
From: gwelch-contegix <111144057+gwelch-contegix@users.noreply.github.com>
Date: Mon, 20 Jan 2025 05:09:31 -0800
Subject: [PATCH 43/52] Fix community support url (#6245)
---
.github/ISSUE_TEMPLATE/config.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 5c422bb47..9d1990ffe 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,7 +1,7 @@
blank_issues_enabled: false
contact_links:
- name: ❓ Community-driven support (Free)
- url: https://docs.mailcow.email/#get-support
+ url: https://docs.mailcow.email/#community-support-and-chat
about: Please use the community forum for questions or assistance
- name: 🔥 Premium Support (Paid)
url: https://www.servercow.de/mailcow?lang=en#support
From 36db68677ca41f68f7117f8d1c6abf53af5adcbe Mon Sep 17 00:00:00 2001
From: Alyx
Date: Mon, 20 Jan 2025 13:10:29 +0000
Subject: [PATCH 44/52] Reduce sa rules download retry limit to 5 (#6225)
Reduces the retry limit for the sa rules download to a more reasonable 5 retries to prevent running in a timeout condition.
---
data/Dockerfiles/dovecot/sa-rules.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/data/Dockerfiles/dovecot/sa-rules.sh b/data/Dockerfiles/dovecot/sa-rules.sh
index 2a513805a..e948d438c 100755
--- a/data/Dockerfiles/dovecot/sa-rules.sh
+++ b/data/Dockerfiles/dovecot/sa-rules.sh
@@ -11,7 +11,7 @@ else
fi
# Deploy
-if curl --connect-timeout 15 --retry 10 --max-time 30 https://www.spamassassin.heinlein-support.de/$(dig txt 1.4.3.spamassassin.heinlein-support.de +short | tr -d '"' | tr -dc '0-9').tar.gz --output /tmp/sa-rules-heinlein.tar.gz; then
+if curl --connect-timeout 15 --retry 5 --max-time 30 https://www.spamassassin.heinlein-support.de/$(dig txt 1.4.3.spamassassin.heinlein-support.de +short | tr -d '"' | tr -dc '0-9').tar.gz --output /tmp/sa-rules-heinlein.tar.gz; then
if gzip -t /tmp/sa-rules-heinlein.tar.gz; then
tar xfvz /tmp/sa-rules-heinlein.tar.gz -C /tmp/sa-rules-heinlein
cat /tmp/sa-rules-heinlein/*cf > /etc/rspamd/custom/sa-rules
From 746915cbddbeac7ca5feac492749448882efc1b8 Mon Sep 17 00:00:00 2001
From: DerLinkman
Date: Mon, 20 Jan 2025 14:21:15 +0100
Subject: [PATCH 45/52] fts: change autoindex to occur on mailboxes of
receiving 20 or more mails daily
---
data/conf/dovecot/conf.d/fts.conf | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/data/conf/dovecot/conf.d/fts.conf b/data/conf/dovecot/conf.d/fts.conf
index acc6f1243..1ad5201f7 100644
--- a/data/conf/dovecot/conf.d/fts.conf
+++ b/data/conf/dovecot/conf.d/fts.conf
@@ -3,6 +3,8 @@ plugin {
fts_autoindex = yes
fts_autoindex_exclude = \Junk
fts_autoindex_exclude2 = \Trash
+ # Tweak this setting if you only want to ensure big and frequent folders are indexed, not all.
+ fts_autoindex_max_recent_msgs = 20
fts = flatcurve
# Maximum term length can be set via the 'maxlen' argument (maxlen is
@@ -26,7 +28,7 @@ plugin {
service indexer-worker {
# Max amount of simultaniously running indexer jobs.
- process_limit=5
+ process_limit=1
# Max amount of RAM used by EACH indexer process.
vsz_limit=128 MB
From 4708b1398b7955e2525b17c1a72844c50b29a0e0 Mon Sep 17 00:00:00 2001
From: DerLinkman
Date: Mon, 20 Jan 2025 15:41:48 +0100
Subject: [PATCH 46/52] update.sh: fix mailcow fts update versioning
---
update.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/update.sh b/update.sh
index 1d0bfe8b6..715ab3fee 100755
--- a/update.sh
+++ b/update.sh
@@ -676,7 +676,7 @@ migrate_solr_config_options() {
solr_volume=$(docker volume ls -qf name=^${COMPOSE_PROJECT_NAME}_solr-vol-1)
if [[ -n $solr_volume ]]; then
- echo -e "\e[34mSolr has been replaced within mailcow since 2024-12.\e[0m"
+ echo -e "\e[34mSolr has been replaced within mailcow since 2025-01.\e[0m"
sleep 1
echo -e "\e[34mTherefore the volume $solr_volume is unused.\e[0m"
sleep 1
@@ -697,7 +697,7 @@ migrate_solr_config_options() {
fi
# Delete old fts.conf before forced switch to flatcurve to ensure update is working properly
- FTS_CONF_PATH="data/conf/dovecot/conf.d/fts.conf"
+ FTS_CONF_PATH="${SCRIPT_DIR}/data/conf/dovecot/conf.d/fts.conf"
if [[ -f "$FTS_CONF_PATH" ]]; then
if grep -q "Autogenerated by mailcow" "$FTS_CONF_PATH"; then
rm -rf $FTS_CONF_PATH
From ee7a8624fcefed734da76bd73185ab50f7f8a5b8 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Tue, 21 Jan 2025 06:38:13 +0100
Subject: [PATCH 47/52] chore(deps): update actions/stale action to v9.1.0
(#6247)
Signed-off-by: milkmaker
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
.github/workflows/close_old_issues_and_prs.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/close_old_issues_and_prs.yml b/.github/workflows/close_old_issues_and_prs.yml
index 391de66d5..af5fd807d 100644
--- a/.github/workflows/close_old_issues_and_prs.yml
+++ b/.github/workflows/close_old_issues_and_prs.yml
@@ -14,7 +14,7 @@ jobs:
pull-requests: write
steps:
- name: Mark/Close Stale Issues and Pull Requests 🗑️
- uses: actions/stale@v9.0.0
+ uses: actions/stale@v9.1.0
with:
repo-token: ${{ secrets.STALE_ACTION_PAT }}
days-before-stale: 60
From 7bcd61ecb553aadc69efa517802ef581d054a261 Mon Sep 17 00:00:00 2001
From: FreddleSpl0it
Date: Wed, 22 Jan 2025 14:30:47 +0100
Subject: [PATCH 48/52] [Nginx] Generate includes for custom configs
---
data/Dockerfiles/nginx/bootstrap.py | 29 +++++++++++++++----
data/conf/nginx/{ => templates}/nginx.conf.j2 | 10 +++++--
.../{ => templates}/sites-default.conf.j2 | 0
docker-compose.yml | 3 +-
4 files changed, 34 insertions(+), 8 deletions(-)
rename data/conf/nginx/{ => templates}/nginx.conf.j2 (96%)
rename data/conf/nginx/{ => templates}/sites-default.conf.j2 (100%)
diff --git a/data/Dockerfiles/nginx/bootstrap.py b/data/Dockerfiles/nginx/bootstrap.py
index d47e6318a..de7824334 100644
--- a/data/Dockerfiles/nginx/bootstrap.py
+++ b/data/Dockerfiles/nginx/bootstrap.py
@@ -2,6 +2,27 @@ import os
import subprocess
from jinja2 import Environment, FileSystemLoader
+def includes_conf(env, template_vars):
+ server_name = "server_name.active"
+ listen_plain = "listen_plain.active"
+ listen_ssl = "listen_ssl.active"
+
+ server_name_config = f"server_name {template_vars['MAILCOW_HOSTNAME']} autodiscover.* autoconfig.* {template_vars['ADDITIONAL_SERVER_NAMES']};"
+ listen_plain_config = f"listen {template_vars['HTTP_PORT']};"
+ listen_ssl_config = f"listen {template_vars['HTTPS_PORT']};"
+ if not template_vars['DISABLE_IPv6']:
+ listen_plain_config += f"\nlisten [::]:{template_vars['HTTP_PORT']};"
+ listen_ssl_config += f"\nlisten [::]:{template_vars['HTTPS_PORT']} ssl;"
+ listen_ssl_config += "\nhttp2 on;"
+
+ with open(f"/etc/nginx/conf.d/{server_name}", "w") as f:
+ f.write(server_name_config)
+
+ with open(f"/etc/nginx/conf.d/{listen_plain}", "w") as f:
+ f.write(listen_plain_config)
+
+ with open(f"/etc/nginx/conf.d/{listen_ssl}", "w") as f:
+ f.write(listen_ssl_config)
def sites_default_conf(env, template_vars):
config_name = "sites-default.conf"
@@ -34,6 +55,7 @@ def prepare_template_vars():
'SOGOHOST': os.getenv("SOGOHOST", ipv4_network + ".248"),
'RSPAMDHOST': os.getenv("RSPAMDHOST", "rspamd-mailcow"),
'PHPFPMHOST': os.getenv("PHPFPMHOST", "php-fpm-mailcow"),
+ 'DISABLE_IPv6': os.getenv("DISABLE_IPv6", "n").lower() in ("y", "yes"),
}
ssl_dir = '/etc/ssl/mail/'
@@ -60,17 +82,14 @@ def prepare_template_vars():
return template_vars
def main():
- env = Environment(loader=FileSystemLoader('./etc/nginx/conf.d'))
+ env = Environment(loader=FileSystemLoader('./etc/nginx/conf.d/templates'))
# Render config
print("Render config")
template_vars = prepare_template_vars()
sites_default_conf(env, template_vars)
nginx_conf(env, template_vars)
-
- # Validate config
- print("Validate config")
- subprocess.run(["nginx", "-qt"])
+ includes_conf(env, template_vars)
if __name__ == "__main__":
diff --git a/data/conf/nginx/nginx.conf.j2 b/data/conf/nginx/templates/nginx.conf.j2
similarity index 96%
rename from data/conf/nginx/nginx.conf.j2
rename to data/conf/nginx/templates/nginx.conf.j2
index 13444129f..1e5481d93 100644
--- a/data/conf/nginx/nginx.conf.j2
+++ b/data/conf/nginx/templates/nginx.conf.j2
@@ -27,6 +27,8 @@ http {
#gzip on;
+ include /etc/nginx/conf.d/*.conf;
+
# map-size.conf:
map_hash_max_size 256;
map_hash_bucket_size 256;
@@ -45,9 +47,11 @@ http {
server {
listen 127.0.0.1:65510; # sogo-auth verify internal
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
- listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
listen {{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl;
+ {% if not DISABLE_IPv6 %}
+ listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
listen [::]:{{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl;
+ {%endif%}
http2 on;
ssl_certificate /etc/ssl/mail/cert.pem;
@@ -103,9 +107,11 @@ http {
{% for cert in valid_cert_dirs %}
server {
listen {{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
- listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
listen {{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl;
+ {% if not DISABLE_IPv6 %}
+ listen [::]:{{ HTTP_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%};
listen [::]:{{ HTTPS_PORT }}{% if NGINX_USE_PROXY_PROTOCOL %} proxy_protocol{%endif%} ssl;
+ {%endif%}
http2 on;
ssl_certificate {{ cert.cert_path }}cert.pem;
diff --git a/data/conf/nginx/sites-default.conf.j2 b/data/conf/nginx/templates/sites-default.conf.j2
similarity index 100%
rename from data/conf/nginx/sites-default.conf.j2
rename to data/conf/nginx/templates/sites-default.conf.j2
diff --git a/docker-compose.yml b/docker-compose.yml
index fc2ad58ca..cd85304b4 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -372,7 +372,7 @@ services:
- php-fpm-mailcow
- sogo-mailcow
- rspamd-mailcow
- image: mailcow/nginx:1.00
+ image: mailcow/nginx:1.01
dns:
- ${IPV4_NETWORK:-172.22.1}.254
environment:
@@ -383,6 +383,7 @@ services:
- TZ=${TZ}
- SKIP_SOGO=${SKIP_SOGO:-n}
- SKIP_RSPAMD=${SKIP_RSPAMD:-n}
+ - DISABLE_IPv6=${DISABLE_IPv6:-n}
- PHPFPMHOST=${PHPFPMHOST:-}
- SOGOHOST=${SOGOHOST:-}
- RSPAMDHOST=${RSPAMDHOST:-}
From 1fca328266eb980da6ca8376db51c9ea201d59c6 Mon Sep 17 00:00:00 2001
From: FreddleSpl0it
Date: Wed, 22 Jan 2025 15:11:46 +0100
Subject: [PATCH 49/52] [Nginx] Disable IPv6 listener for Rspamd dynmaps when
DISABLE_IPv6=y
---
data/conf/nginx/templates/nginx.conf.j2 | 2 ++
1 file changed, 2 insertions(+)
diff --git a/data/conf/nginx/templates/nginx.conf.j2 b/data/conf/nginx/templates/nginx.conf.j2
index 1e5481d93..a6f32ebb7 100644
--- a/data/conf/nginx/templates/nginx.conf.j2
+++ b/data/conf/nginx/templates/nginx.conf.j2
@@ -65,7 +65,9 @@ http {
# rspamd dynmaps:
server {
listen 8081;
+ {% if not DISABLE_IPv6 %}
listen [::]:8081;
+ {%endif%}
index index.php index.html;
server_name _;
error_log /var/log/nginx/error.log;
From a30f6696a39d371424300e22182317a0317575b7 Mon Sep 17 00:00:00 2001
From: DerLinkman
Date: Thu, 23 Jan 2025 08:30:48 +0100
Subject: [PATCH 50/52] update.sh: fixed --force for solr-removal + code
optimization
---
update.sh | 24 +++++++++++-------------
1 file changed, 11 insertions(+), 13 deletions(-)
diff --git a/update.sh b/update.sh
index 715ab3fee..94c1a8423 100755
--- a/update.sh
+++ b/update.sh
@@ -676,23 +676,21 @@ migrate_solr_config_options() {
solr_volume=$(docker volume ls -qf name=^${COMPOSE_PROJECT_NAME}_solr-vol-1)
if [[ -n $solr_volume ]]; then
- echo -e "\e[34mSolr has been replaced within mailcow since 2025-01.\e[0m"
+ echo -e "\e[34mSolr has been replaced within mailcow since 2025-01.\nThe volume $solr_volume is unused.\e[0m"
sleep 1
- echo -e "\e[34mTherefore the volume $solr_volume is unused.\e[0m"
- sleep 1
- read -r -p "Would you like to remove the $solr_volume? " response
- if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
- echo -e "\e[33mRemoving $solr_volume...\e[0m"
- docker volume rm $solr_volume
- if [[ $? != 0 ]]; then
- echo -e "\e[31mCould not remove the volume... Please remove it manually!\e[0m"
+ if [ ! "$FORCE" ]; then
+ read -r -p "Remove $solr_volume? [y/N] " response
+ if [[ "$response" =~ ^([yY][eE][sS]|[yY])+$ ]]; then
+ echo -e "\e[33mRemoving $solr_volume...\e[0m"
+ docker volume rm $solr_volume || echo -e "\e[31mFailed to remove. Remove it manually!\e[0m" && exit
+ echo -e "\e[32mSuccessfully removed $solr_volume!\e[0m"
else
- echo -e "\e[32mSucessfully removed $solr_volume!\e[0m"
+ echo -e "Not removing $solr_volume. Run \`docker volume rm $solr_volume\` manually if needed."
fi
else
- echo "Ok! Not removing $solr_volume then."
- echo "Once you decided on removing the volume simply run docker volume rm $solr_volume to remove it manually."
- echo "This can be done anytime. mailcow does not use this volume anymore."
+ echo -e "\e[33mForce removing $solr_volume...\e[0m"
+ docker volume rm $solr_volume || echo -e "\e[31mFailed to remove. Remove it manually!\e[0m" && exit
+ echo -e "\e[32mSuccessfully removed $solr_volume!\e[0m"
fi
fi
From 5a04942d89b220da3f1e5f5d1c5f318fca19d2f1 Mon Sep 17 00:00:00 2001
From: DerLinkman
Date: Thu, 23 Jan 2025 08:38:14 +0100
Subject: [PATCH 51/52] update.sh: changed SKIP_FTS default to y instead n for
updates
---
update.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/update.sh b/update.sh
index 94c1a8423..128abfda7 100755
--- a/update.sh
+++ b/update.sh
@@ -473,7 +473,7 @@ adapt_new_options() {
echo "Adding new option \"${option}\" to mailcow.conf"
echo '# Skip FTS (Fulltext Search) for Dovecot on low-memory systems or if you simply want to disable it.' >> mailcow.conf
echo "# Dovecot inside mailcow use Flatcurve as FTS Backend." >> mailcow.conf
- echo "SKIP_FTS=n" >> mailcow.conf
+ echo "SKIP_FTS=y" >> mailcow.conf
fi
elif [[ ${option} == "FTS_PROCS" ]]; then
if ! grep -q ${option} mailcow.conf; then
From 1dac8f1f66ad1767bf7cb5c64f4a95a2af94f2c8 Mon Sep 17 00:00:00 2001
From: DerLinkman
Date: Thu, 23 Jan 2025 08:42:22 +0100
Subject: [PATCH 52/52] scripts: changed SKIP_FTS text to warn on lower
threaded systems
---
generate_config.sh | 2 +-
update.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/generate_config.sh b/generate_config.sh
index 3044ab8d7..8f03e3899 100755
--- a/generate_config.sh
+++ b/generate_config.sh
@@ -379,7 +379,7 @@ SKIP_CLAMD=${SKIP_CLAMD}
SKIP_SOGO=n
-# Skip FTS (Fulltext Search) for Dovecot on low-memory systems or if you simply want to disable it.
+# Skip FTS (Fulltext Search) for Dovecot on low-memory, low-threaded systems or if you simply want to disable it.
# Dovecot inside mailcow use Flatcurve as FTS Backend.
SKIP_FTS=n
diff --git a/update.sh b/update.sh
index 128abfda7..268fe7326 100755
--- a/update.sh
+++ b/update.sh
@@ -471,7 +471,7 @@ adapt_new_options() {
elif [[ ${option} == "SKIP_FTS" ]]; then
if ! grep -q ${option} mailcow.conf; then
echo "Adding new option \"${option}\" to mailcow.conf"
- echo '# Skip FTS (Fulltext Search) for Dovecot on low-memory systems or if you simply want to disable it.' >> mailcow.conf
+ echo '# Skip FTS (Fulltext Search) for Dovecot on low-memory, low-threaded systems or if you simply want to disable it.' >> mailcow.conf
echo "# Dovecot inside mailcow use Flatcurve as FTS Backend." >> mailcow.conf
echo "SKIP_FTS=y" >> mailcow.conf
fi