diff --git a/.github/workflows/close_old_issues_and_prs.yml b/.github/workflows/close_old_issues_and_prs.yml index bba04b0d1..e55b27068 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@v10.4.0 + uses: actions/stale@v10.2.0 with: repo-token: ${{ secrets.STALE_ACTION_PAT }} days-before-stale: 60 diff --git a/.github/workflows/image_builds.yml b/.github/workflows/image_builds.yml index aa56b0381..c8ec7ccae 100644 --- a/.github/workflows/image_builds.yml +++ b/.github/workflows/image_builds.yml @@ -27,7 +27,7 @@ jobs: - "watchdog-mailcow" runs-on: ubuntu-latest steps: - - uses: actions/checkout@v7 + - uses: actions/checkout@v6 - name: Setup Docker run: | curl -sSL https://get.docker.com/ | CHANNEL=stable sudo sh diff --git a/.github/workflows/pr_to_nightly.yml b/.github/workflows/pr_to_nightly.yml index 8d6b2524d..d0f8ccf74 100644 --- a/.github/workflows/pr_to_nightly.yml +++ b/.github/workflows/pr_to_nightly.yml @@ -8,11 +8,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout repository - uses: actions/checkout@v7 + uses: actions/checkout@v6 with: fetch-depth: 0 - name: Run the Action - uses: devops-infra/action-pull-request@v1.4.0 + uses: devops-infra/action-pull-request@v1.1.1 with: github_token: ${{ secrets.PRTONIGHTLY_ACTION_PAT }} title: Automatic PR to nightly from ${{ github.event.repository.updated_at}} diff --git a/.github/workflows/rebuild_backup_image.yml b/.github/workflows/rebuild_backup_image.yml index 4490afee1..b18d339ba 100644 --- a/.github/workflows/rebuild_backup_image.yml +++ b/.github/workflows/rebuild_backup_image.yml @@ -13,7 +13,7 @@ jobs: packages: write steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@v6 - name: Set up QEMU uses: docker/setup-qemu-action@v4 diff --git a/.github/workflows/update_postscreen_access_list.yml b/.github/workflows/update_postscreen_access_list.yml index ed63281c7..066616aee 100644 --- a/.github/workflows/update_postscreen_access_list.yml +++ b/.github/workflows/update_postscreen_access_list.yml @@ -15,7 +15,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v7 + uses: actions/checkout@v6 - name: Generate postscreen_access.cidr run: | diff --git a/README.md b/README.md index 8844c7482..40288f10e 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,6 @@ A big thank you to everyone supporting us on GitHub Sponsors—your contribution - ### 50$/Month Sponsors " ENV PIP_BREAK_SYSTEM_PACKAGES=1 diff --git a/data/Dockerfiles/phpfpm/Dockerfile b/data/Dockerfiles/phpfpm/Dockerfile index ca252163a..7917d7f7d 100644 --- a/data/Dockerfiles/phpfpm/Dockerfile +++ b/data/Dockerfiles/phpfpm/Dockerfile @@ -7,13 +7,13 @@ ARG APCU_PECL_VERSION=5.1.28 # renovate: datasource=github-tags depName=Imagick/imagick versioning=semver-coerced extractVersion=(?.*)$ ARG IMAGICK_PECL_VERSION=3.8.1 # renovate: datasource=github-tags depName=php/pecl-mail-mailparse versioning=semver-coerced extractVersion=^v(?.*)$ -ARG MAILPARSE_PECL_VERSION=3.2.0 +ARG MAILPARSE_PECL_VERSION=3.1.9 # renovate: datasource=github-tags depName=php-memcached-dev/php-memcached versioning=semver-coerced extractVersion=^v(?.*)$ ARG MEMCACHED_PECL_VERSION=3.4.0 # renovate: datasource=github-tags depName=phpredis/phpredis versioning=semver-coerced extractVersion=(?.*)$ ARG REDIS_PECL_VERSION=6.3.0 # renovate: datasource=github-tags depName=composer/composer versioning=semver-coerced extractVersion=(?.*)$ -ARG COMPOSER_VERSION=2.10.2 +ARG COMPOSER_VERSION=2.9.5 RUN apk add -U --no-cache autoconf \ aspell-dev \ diff --git a/data/Dockerfiles/postfix/Dockerfile b/data/Dockerfiles/postfix/Dockerfile index cf0647692..994612ec4 100644 --- a/data/Dockerfiles/postfix/Dockerfile +++ b/data/Dockerfiles/postfix/Dockerfile @@ -1,4 +1,4 @@ -FROM debian:trixie-slim +FROM debian:bookworm-slim LABEL maintainer="The Infrastructure Company GmbH " diff --git a/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf b/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf index bbc9420fe..8e15932a2 100644 --- a/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf +++ b/data/Dockerfiles/postfix/syslog-ng-redis_slave.conf @@ -1,4 +1,4 @@ -@version: 4.8 +@version: 3.38 @include "scl.conf" options { chain_hostnames(off); @@ -7,7 +7,7 @@ options { dns_cache(no); use_fqdn(no); owner("root"); group("adm"); perm(0640); - stats(freq(0)); + stats_freq(0); bad_hostname("^gconfd$"); }; source s_src { diff --git a/data/Dockerfiles/postfix/syslog-ng.conf b/data/Dockerfiles/postfix/syslog-ng.conf index 8f09d04a4..fc7d1aa0f 100644 --- a/data/Dockerfiles/postfix/syslog-ng.conf +++ b/data/Dockerfiles/postfix/syslog-ng.conf @@ -1,4 +1,4 @@ -@version: 4.8 +@version: 3.38 @include "scl.conf" options { chain_hostnames(off); @@ -7,7 +7,7 @@ options { dns_cache(no); use_fqdn(no); owner("root"); group("adm"); perm(0640); - stats(freq(0)); + stats_freq(0); bad_hostname("^gconfd$"); }; source s_src { diff --git a/data/Dockerfiles/rspamd/Dockerfile b/data/Dockerfiles/rspamd/Dockerfile index d37d1226a..d0c710428 100644 --- a/data/Dockerfiles/rspamd/Dockerfile +++ b/data/Dockerfiles/rspamd/Dockerfile @@ -2,7 +2,7 @@ FROM debian:trixie-slim LABEL maintainer="The Infrastructure Company GmbH " ARG DEBIAN_FRONTEND=noninteractive -ARG RSPAMD_VER=rspamd_4.1.0-1~e2b0b18 +ARG RSPAMD_VER=rspamd_3.14.3-1~236eb65 ARG CODENAME=trixie ENV LC_ALL=C diff --git a/data/Dockerfiles/sogo/Dockerfile b/data/Dockerfiles/sogo/Dockerfile index b4b401e8c..1c7287200 100644 --- a/data/Dockerfiles/sogo/Dockerfile +++ b/data/Dockerfiles/sogo/Dockerfile @@ -1,6 +1,6 @@ # SOGo built from source to enable security patch application # Repository: https://github.com/Alinto/sogo -# Version: SOGo-5.12.9 +# Version: SOGo-5.12.8 # # Applied security patches: # - @@ -12,8 +12,8 @@ FROM debian:bookworm LABEL maintainer="The Infrastructure Company GmbH " ARG DEBIAN_FRONTEND=noninteractive -ARG SOGO_VERSION=SOGo-5.12.9 -ARG SOPE_VERSION=SOPE-5.12.9 +ARG SOGO_VERSION=SOGo-5.12.8 +ARG SOPE_VERSION=SOPE-5.12.8 # Security patches to apply (space-separated commit hashes) ARG SOGO_SECURITY_PATCHES="" # renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?.*)$ diff --git a/data/Dockerfiles/unbound/Dockerfile b/data/Dockerfiles/unbound/Dockerfile index b1ec99e4f..7c4921384 100644 --- a/data/Dockerfiles/unbound/Dockerfile +++ b/data/Dockerfiles/unbound/Dockerfile @@ -2,14 +2,11 @@ FROM alpine:3.23 LABEL maintainer = "The Infrastructure Company GmbH " -# install unbound from alpine:edge to get security patches -RUN apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/edge/main unbound - -# install other packages from regular alpine stable repo RUN apk add --update --no-cache \ curl \ bind-tools \ coreutils \ + unbound \ bash \ openssl \ drill \ diff --git a/data/conf/postfix/main.cf b/data/conf/postfix/main.cf index 080be499a..f091cb3f9 100644 --- a/data/conf/postfix/main.cf +++ b/data/conf/postfix/main.cf @@ -37,7 +37,7 @@ postscreen_access_list = permit_mynetworks, cidr:/opt/postfix/conf/postscreen_access.cidr, tcp:127.0.0.1:10027 postscreen_bare_newline_enable = no -postscreen_denylist_action = drop +postscreen_blacklist_action = drop postscreen_cache_cleanup_interval = 24h postscreen_cache_map = proxy:btree:$data_directory/postscreen_cache postscreen_dnsbl_action = enforce @@ -107,6 +107,8 @@ smtpd_sender_restrictions = reject_authenticated_sender_login_mismatch, reject_unknown_sender_domain smtpd_soft_error_limit = 3 smtpd_tls_auth_only = yes +smtpd_tls_dh1024_param_file = /etc/ssl/mail/dhparams.pem +smtpd_tls_eecdh_grade = auto smtpd_tls_exclude_ciphers = ECDHE-RSA-RC4-SHA, RC4, aNULL, DES-CBC3-SHA, ECDHE-RSA-DES-CBC3-SHA, EDH-RSA-DES-CBC3-SHA smtpd_tls_loglevel = 1 diff --git a/data/conf/postfix/master.cf b/data/conf/postfix/master.cf index fb49f2df2..d5114df28 100644 --- a/data/conf/postfix/master.cf +++ b/data/conf/postfix/master.cf @@ -29,6 +29,7 @@ smtps inet n - n - - smtpd # TLS protocol can be modified by setting submission_smtpd_tls_mandatory_protocols in extra.cf submission inet n - n - - smtpd -o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject + -o smtpd_enforce_tls=yes -o smtpd_tls_security_level=encrypt -o smtpd_tls_mandatory_protocols=$submission_smtpd_tls_mandatory_protocols -o tls_preempt_cipherlist=yes @@ -37,6 +38,7 @@ submission inet n - n - - smtpd 10587 inet n - n - - smtpd -o smtpd_upstream_proxy_protocol=haproxy -o smtpd_client_restrictions=permit_mynetworks,permit_sasl_authenticated,reject + -o smtpd_enforce_tls=yes -o smtpd_tls_security_level=encrypt -o smtpd_tls_mandatory_protocols=$submission_smtpd_tls_mandatory_protocols -o tls_preempt_cipherlist=yes diff --git a/data/conf/postfix/postscreen_access.cidr b/data/conf/postfix/postscreen_access.cidr index 6fcedff95..285ea7a81 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 Wed Jul 1 00:51:20 UTC 2026 +# Whitelist generated by Postwhite v3.4 on Fri May 1 00:43:37 UTC 2026 # https://github.com/stevejenkins/postwhite/ -# 2251 total rules +# 2249 total rules 2a00:1450:4000::/36 permit 2a00:1450:4864::/56 permit 2a01:111:f400::/48 permit @@ -56,8 +56,14 @@ 8.25.194.0/23 permit 8.25.196.0/23 permit 8.36.116.0/24 permit +8.39.54.0/23 permit +8.39.54.250/31 permit 8.39.144.0/24 permit +8.40.222.0/23 permit +8.40.222.250/31 permit 12.130.86.238 permit +13.107.213.40 permit +13.107.246.40 permit 13.108.16.0/20 permit 13.110.208.0/21 permit 13.110.209.0/24 permit @@ -67,6 +73,7 @@ 13.111.191.0/24 permit 13.216.7.111 permit 13.216.54.180 permit +13.247.164.219 permit 15.200.21.50 permit 15.200.44.248 permit 15.200.201.185 permit @@ -170,6 +177,7 @@ 34.215.104.144 permit 34.218.115.239 permit 34.225.212.172 permit +34.241.242.183 permit 35.83.148.184 permit 35.155.198.111 permit 35.158.23.94 permit @@ -193,6 +201,7 @@ 40.233.64.216 permit 40.233.83.78 permit 40.233.88.28 permit +43.239.212.33 permit 44.206.138.57 permit 44.210.169.44 permit 44.217.45.156 permit @@ -275,6 +284,7 @@ 51.83.17.38 permit 52.1.14.157 permit 52.5.230.59 permit +52.6.74.205 permit 52.12.53.23 permit 52.13.214.179 permit 52.26.1.71 permit @@ -331,6 +341,7 @@ 54.244.54.130 permit 54.244.242.0/24 permit 54.255.61.23 permit +56.124.6.228 permit 57.103.64.0/18 permit 57.129.93.249 permit 62.13.128.0/24 permit @@ -397,6 +408,7 @@ 65.110.161.77 permit 65.123.29.213 permit 65.123.29.220 permit +65.154.166.0/24 permit 65.212.180.36 permit 66.102.0.0/20 permit 66.119.150.192/26 permit @@ -1210,6 +1222,9 @@ 99.78.197.208/28 permit 103.9.96.0/22 permit 103.28.42.0/24 permit +103.84.217.15 permit +103.84.217.238 permit +103.89.75.238 permit 103.151.192.0/23 permit 103.168.172.128/27 permit 103.237.104.0/22 permit @@ -1370,6 +1385,9 @@ 117.120.16.0/21 permit 119.42.242.52/31 permit 119.42.242.156 permit +121.244.91.48 permit +121.244.91.52 permit +122.15.156.182 permit 123.126.78.64/29 permit 124.108.96.24/31 permit 124.108.96.28/31 permit @@ -1452,7 +1470,21 @@ 134.170.141.64/26 permit 134.170.143.0/24 permit 134.170.174.0/24 permit +135.84.80.0/24 permit +135.84.81.0/24 permit +135.84.82.0/24 permit +135.84.83.0/24 permit 135.84.216.0/22 permit +136.143.160.0/24 permit +136.143.161.0/24 permit +136.143.162.0/24 permit +136.143.176.0/24 permit +136.143.177.0/24 permit +136.143.178.49 permit +136.143.182.0/23 permit +136.143.184.0/24 permit +136.143.188.0/24 permit +136.143.190.0/23 permit 136.146.128.0/20 permit 136.147.128.0/20 permit 136.147.135.0/24 permit @@ -1472,6 +1504,7 @@ 139.138.46.219 permit 139.138.57.55 permit 139.138.58.119 permit +139.167.79.86 permit 139.177.108.0/25 permit 139.180.17.0/24 permit 140.238.148.191 permit @@ -1521,14 +1554,12 @@ 147.243.128.26 permit 148.105.0.0/16 permit 148.105.8.0/21 permit -148.116.32.128/25 permit 149.72.0.0/16 permit 149.72.234.184 permit 149.72.248.236 permit 149.97.173.180 permit 149.118.160.128/25 permit 150.136.21.199 permit -150.171.109.183 permit 150.230.98.160 permit 151.145.38.14 permit 152.67.105.195 permit @@ -1606,9 +1637,8 @@ 164.177.132.168/30 permit 165.1.100.0/25 permit 165.173.128.0/24 permit -165.173.180.0/24 permit +165.173.180.1 permit 165.173.180.250/31 permit -165.173.182.0/24 permit 165.173.182.250/31 permit 165.173.189.205 permit 166.78.68.0/22 permit @@ -1643,6 +1673,19 @@ 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.138.0/24 permit +169.148.142.10 permit +169.148.142.33 permit +169.148.144.0/25 permit +169.148.144.10 permit +169.148.146.0/23 permit +169.148.174.10 permit +169.148.175.3 permit +169.148.179.3 permit +169.148.188.0/24 permit +169.148.188.182 permit 170.9.232.254 permit 170.10.128.0/24 permit 170.10.129.0/24 permit @@ -1657,7 +1700,6 @@ 173.203.81.39 permit 173.224.161.128/25 permit 173.224.165.0/26 permit -173.224.166.48/28 permit 174.36.84.8/29 permit 174.36.84.16/29 permit 174.36.84.32/29 permit @@ -1849,7 +1891,16 @@ 199.16.156.0/22 permit 199.33.145.1 permit 199.33.145.32 permit +199.34.22.36 permit 199.59.148.0/22 permit +199.67.80.2 permit +199.67.80.20 permit +199.67.82.2 permit +199.67.82.20 permit +199.67.84.0/24 permit +199.67.86.0/24 permit +199.67.88.0/24 permit +199.67.90.0/24 permit 199.101.161.130 permit 199.101.162.0/25 permit 199.122.120.0/21 permit @@ -1905,6 +1956,8 @@ 204.92.114.187 permit 204.92.114.203 permit 204.92.114.204/31 permit +204.141.32.0/23 permit +204.141.42.0/23 permit 204.216.164.202 permit 204.220.160.0/21 permit 204.220.168.0/21 permit @@ -2178,7 +2231,7 @@ 2001:748:400:3301::4 permit 2404:6800:4000::/36 permit 2404:6800:4864::/56 permit -2603:1061:14:1c2::1 permit +2603:1061:14:72::1 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 diff --git a/data/conf/rspamd/local.d/metadata_exporter.conf b/data/conf/rspamd/local.d/metadata_exporter.conf index cc85faacd..daaa79b4e 100644 --- a/data/conf/rspamd/local.d/metadata_exporter.conf +++ b/data/conf/rspamd/local.d/metadata_exporter.conf @@ -3,7 +3,8 @@ rules { backend = "http"; url = "http://nginx:9081/pipe.php"; selector = "reject_no_global_bl"; - formatter = "multipart"; + formatter = "default"; + meta_headers = true; } RLINFO { backend = "http"; @@ -15,7 +16,8 @@ rules { backend = "http"; url = "http://nginx:9081/pushover.php"; selector = "mailcow_rcpt"; - formatter = "multipart"; + formatter = "json"; + meta_headers = true; } } diff --git a/data/conf/rspamd/meta_exporter/pipe.php b/data/conf/rspamd/meta_exporter/pipe.php index 0a9ed59e2..003639b08 100644 --- a/data/conf/rspamd/meta_exporter/pipe.php +++ b/data/conf/rspamd/meta_exporter/pipe.php @@ -32,42 +32,47 @@ function parse_email($email) { $a = strrpos($email, '@'); return array('local' => substr($email, 0, $a), 'domain' => substr(substr($email, $a), 1)); } -// rspamd metadata_exporter (multipart formatter): -// - $_POST['metadata'] JSON with the rspamd metadata -// - $_FILES['message'] raw RFC822 message -if (empty($_POST['metadata']) || !isset($_FILES['message']) || $_FILES['message']['error'] !== UPLOAD_ERR_OK) { - error_log("QUARANTINE: missing multipart parts from rspamd" . PHP_EOL); - http_response_code(400); - exit; +if (!function_exists('getallheaders')) { + function getallheaders() { + if (!is_array($_SERVER)) { + return array(); + } + $headers = array(); + foreach ($_SERVER as $name => $value) { + if (substr($name, 0, 5) == 'HTTP_') { + $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; + } + } + return $headers; + } } -$meta = json_decode($_POST['metadata'], true); -if (!is_array($meta)) { - error_log("QUARANTINE: cannot decode metadata JSON" . PHP_EOL); - http_response_code(400); - exit; -} - -$raw_data_content = file_get_contents($_FILES['message']['tmp_name']); +$raw_data_content = file_get_contents('php://input'); $raw_data = mb_convert_encoding($raw_data_content, 'HTML-ENTITIES', "UTF-8"); -$raw_size = (int)$_FILES['message']['size']; +$headers = getallheaders(); -$qid = $meta['qid'] ?? 'unknown'; -$subject = iconv_mime_decode($meta['subject'] ?? ''); -$score = $meta['score'] ?? 0; -$rcpts = $meta['rcpt'] ?? array(); -$user = $meta['user'] ?? 'unknown'; -$ip = $meta['ip'] ?? 'unknown'; -$action = $meta['action'] ?? 'no action'; -$sender = $meta['from'] ?? ''; -$symbols = json_encode($meta['symbols'] ?? array()); -$fuzzy = json_encode(is_array($meta['fuzzy'] ?? null) ? $meta['fuzzy'] : array()); +$qid = $headers['X-Rspamd-Qid']; +$fuzzy = $headers['X-Rspamd-Fuzzy']; +$subject = iconv_mime_decode($headers['X-Rspamd-Subject']); +$score = $headers['X-Rspamd-Score']; +$rcpts = $headers['X-Rspamd-Rcpt']; +$user = $headers['X-Rspamd-User']; +$ip = $headers['X-Rspamd-Ip']; +$action = $headers['X-Rspamd-Action']; +$sender = $headers['X-Rspamd-From']; +$symbols = $headers['X-Rspamd-Symbols']; + +$raw_size = (int)$_SERVER['CONTENT_LENGTH']; if (empty($sender)) { error_log("QUARANTINE: Unknown sender, assuming empty-env-from@localhost" . PHP_EOL); $sender = 'empty-env-from@localhost'; } +if ($fuzzy == 'unknown') { + $fuzzy = '[]'; +} + try { $max_size = (int)$redis->Get('Q_MAX_SIZE'); if (($max_size * 1048576) < $raw_size) { @@ -89,7 +94,7 @@ catch (RedisException $e) { $rcpt_final_mailboxes = array(); // Loop through all rcpts -foreach ($rcpts as $rcpt) { +foreach (json_decode($rcpts, true) as $rcpt) { // Remove tag $rcpt = preg_replace('/^(.*?)\+.*(@.*)$/', '$1$2', $rcpt); diff --git a/data/conf/rspamd/meta_exporter/pushover.php b/data/conf/rspamd/meta_exporter/pushover.php index a2cd0995b..efe5fdd52 100644 --- a/data/conf/rspamd/meta_exporter/pushover.php +++ b/data/conf/rspamd/meta_exporter/pushover.php @@ -32,46 +32,50 @@ function parse_email($email) { $a = strrpos($email, '@'); return array('local' => substr($email, 0, $a), 'domain' => substr(substr($email, $a), 1)); } -// rspamd metadata_exporter (multipart formatter): metadata JSON arrives as $_POST['metadata']. -if (empty($_POST['metadata'])) { - error_log("NOTIFY: missing metadata part from rspamd" . PHP_EOL); - http_response_code(400); - exit; +if (!function_exists('getallheaders')) { + function getallheaders() { + if (!is_array($_SERVER)) { + return array(); + } + $headers = array(); + foreach ($_SERVER as $name => $value) { + if (substr($name, 0, 5) == 'HTTP_') { + $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value; + } + } + return $headers; + } } -$meta = json_decode($_POST['metadata'], true); -if (!is_array($meta)) { - error_log("NOTIFY: cannot decode metadata JSON" . PHP_EOL); - http_response_code(400); - exit; -} +$headers = getallheaders(); +$json_body = json_decode(file_get_contents('php://input')); -$qid = $meta['qid'] ?? 'unknown'; -$rcpts = $meta['rcpt'] ?? array(); -$sender = $meta['from'] ?? ''; -$ip = $meta['ip'] ?? 'unknown'; -$subject = iconv_mime_decode($meta['subject'] ?? ''); -$messageid= $meta['message_id'] ?? ''; +$qid = $headers['X-Rspamd-Qid']; +$rcpts = $headers['X-Rspamd-Rcpt']; +$sender = $headers['X-Rspamd-From']; +$ip = $headers['X-Rspamd-Ip']; +$subject = iconv_mime_decode($headers['X-Rspamd-Subject']); +$messageid= $json_body->message_id; $priority = 0; -$symbols_array = $meta['symbols'] ?? array(); +$symbols_array = json_decode($headers['X-Rspamd-Symbols'], true); if (is_array($symbols_array)) { foreach ($symbols_array as $symbol) { - if (($symbol['name'] ?? null) == 'HAS_X_PRIO_ONE') { + if ($symbol['name'] == 'HAS_X_PRIO_ONE') { $priority = 1; break; } } } -$sender_address = $meta['header_from'][0] ?? ''; +$sender_address = $json_body->header_from[0]; $sender_name = '-'; if (preg_match('/(?.*?)<(?
.*?)>/i', $sender_address, $matches)) { $sender_address = $matches['address']; $sender_name = trim($matches['name'], '"\' '); } -$to_address = $meta['header_to'][0] ?? ''; +$to_address = $json_body->header_to[0]; $to_name = '-'; if (preg_match('/(?.*?)<(?
.*?)>/i', $to_address, $matches)) { $to_address = $matches['address']; @@ -81,7 +85,7 @@ if (preg_match('/(?.*?)<(?
.*?)>/i', $to_address, $matches)) { $rcpt_final_mailboxes = array(); // Loop through all rcpts -foreach ($rcpts as $rcpt) { +foreach (json_decode($rcpts, true) as $rcpt) { // Remove tag $rcpt = preg_replace('/^(.*?)\+.*(@.*)$/', '$1$2', $rcpt); diff --git a/data/web/api/openapi.yaml b/data/web/api/openapi.yaml index 77c58b609..cf54f6add 100644 --- a/data/web/api/openapi.yaml +++ b/data/web/api/openapi.yaml @@ -1072,7 +1072,6 @@ paths: password2: "*" quota: "3072" force_pw_update: "1" - force_tfa: "1" tls_enforce_in: "1" tls_enforce_out: "1" tags: ["tag1", "tag2"] @@ -1119,7 +1118,6 @@ paths: password2: atedismonsin quota: "3072" force_pw_update: "1" - force_tfa: "1" tls_enforce_in: "1" tls_enforce_out: "1" tags: ["tag1", "tag2"] @@ -1153,9 +1151,6 @@ paths: force_pw_update: description: forces the user to update its password on first login type: boolean - force_tfa: - description: force 2FA enrollment at login - type: boolean tls_enforce_in: description: force inbound email tls encryption type: boolean @@ -2515,7 +2510,7 @@ paths: description: >- Using this endpoint you can perform actions on quarantine items. It is possible to release emails from quarantine into to the inbox, or learn them as ham to improve Rspamd filtering. - You must provide the quarantine item IDs. You can get the IDs using the GET method. + You must provide the quarantine item IDs. You can get the IDs using the GET method. operationId: Edit mails in Quarantine requestBody: content: @@ -3419,7 +3414,6 @@ paths: - mailbox - active: "1" force_pw_update: "0" - force_tfa: "0" name: Full name password: "*" password2: "*" @@ -3470,7 +3464,6 @@ paths: attr: active: "1" force_pw_update: "0" - force_tfa: "0" name: Full name authsource: mailcow password: "" @@ -3494,9 +3487,6 @@ paths: force_pw_update: description: force user to change password on next login type: boolean - force_tfa: - description: force 2FA enrollment at login - type: boolean name: description: Full name of the mailbox user type: string @@ -4891,7 +4881,6 @@ paths: - active: "1" attributes: force_pw_update: "0" - force_tfa: "0" mailbox_format: "maildir:" quarantine_notification: never sogo_access: "1" @@ -5816,7 +5805,6 @@ paths: - active: "1" attributes: force_pw_update: "0" - force_tfa: "0" mailbox_format: "maildir:" quarantine_notification: never sogo_access: "1" diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index a9f17705d..adb330ea8 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -3505,6 +3505,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { // Track affected mailboxes for SOGo update $update_sogo_mailboxes[] = $username; } + return true; break; case 'mailbox_rename': $domain = $_data['domain']; @@ -3827,7 +3828,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $attr["rl_frame"] = (!empty($_data['rl_frame'])) ? $_data['rl_frame'] : $is_now['rl_frame']; $attr["rl_value"] = (!empty($_data['rl_value'])) ? $_data['rl_value'] : $is_now['rl_value']; $attr["force_pw_update"] = isset($_data['force_pw_update']) ? intval($_data['force_pw_update']) : $is_now['force_pw_update']; - $attr["force_tfa"] = isset($_data['force_tfa']) ? intval($_data['force_tfa']) : $is_now['force_tfa']; $attr["sogo_access"] = isset($_data['sogo_access']) ? intval($_data['sogo_access']) : $is_now['sogo_access']; $attr["active"] = isset($_data['active']) ? intval($_data['active']) : $is_now['active']; $attr["tls_enforce_in"] = isset($_data['tls_enforce_in']) ? intval($_data['tls_enforce_in']) : $is_now['tls_enforce_in']; @@ -6127,6 +6127,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { // Track affected mailboxes for SOGo update $update_sogo_mailboxes[] = $username; } + return true; break; case 'mailbox_templates': if ($_SESSION['mailcow_cc_role'] != "admin") { diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index 0a0192798..e8edb9940 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -424,11 +424,6 @@ $(document).ready(function() { } else { $('#force_pw_update').prop('checked', false); } - if (template.force_tfa == 1){ - $('#force_tfa').prop('checked', true); - } else { - $('#force_tfa').prop('checked', false); - } if (template.sogo_access == 1){ $('#sogo_access').prop('checked', true); } else { @@ -1247,7 +1242,6 @@ jQuery(function($){ item.attributes.eas_access = '' + (item.attributes.eas_access == 1 ? '1' : '0') + ''; item.attributes.dav_access = '' + (item.attributes.dav_access == 1 ? '1' : '0') + ''; item.attributes.sogo_access = '' + (item.attributes.sogo_access == 1 ? '1' : '0') + ''; - item.attributes.force_tfa = '' + (item.attributes.force_tfa == 1 ? '1' : '0') + ''; if (item.attributes.quarantine_notification === 'never') { item.attributes.quarantine_notification = lang.never; } else if (item.attributes.quarantine_notification === 'hourly') { @@ -1391,11 +1385,6 @@ jQuery(function($){ return 1==data?'':''; } }, - { - title: lang.force_tfa, - data: 'attributes.force_tfa', - defaultContent: '' - }, { title: lang_edit.ratelimit, data: 'attributes.ratelimit', diff --git a/data/web/lang/lang.de-de.json b/data/web/lang/lang.de-de.json index c19eb209b..3672762df 100644 --- a/data/web/lang/lang.de-de.json +++ b/data/web/lang/lang.de-de.json @@ -150,7 +150,7 @@ "arrival_time": "Ankunftszeit (Serverzeit)", "authed_user": "Auth. Benutzer", "ays": "Soll der Vorgang wirklich ausgeführt werden?", - "ban_list_info": "Übersicht ausgesperrter Netzwerke: Netzwerk (verbleibende Bannzeit) - [Aktionen].
IPs, die zum Entsperren eingereiht werden, verlassen die Liste aktiver Banns nach wenigen Sekunden.
Rote Labels kennzeichnen aktive permanente Sperren durch Denylisting.", + "ban_list_info": "Übersicht ausgesperrter Netzwerke: Netzwerk (verbleibende Bannzeit) - [Aktionen].
IPs, die zum Entsperren eingereiht werden, verlassen die Liste aktiver Banns nach wenigen Sekunden.
Rote Labels sind Indikatoren für aktive Allowlist-Einträge.", "change_logo": "Logo ändern", "configuration": "Konfiguration", "convert_html_to_text": "Konvertiere HTML zu reinem Text", @@ -1086,7 +1086,7 @@ "rspamd_result": "Rspamd-Ergebnis", "sender": "Sender (SMTP)", "sender_header": "Sender (\"From\"-Header)", - "settings_info": "Maximale Anzahl der zurückgehaltenen E-Mails (pro Mailbox): %s
Maximale Größe einer zu speichernden E-Mail: %s MiB", + "settings_info": "Maximale Anzahl der zurückgehaltenen E-Mails: %s
Maximale Größe einer zu speichernden E-Mail: %s MiB", "show_item": "Details", "spam": "Spam", "spam_score": "Bewertung", diff --git a/data/web/lang/lang.en-gb.json b/data/web/lang/lang.en-gb.json index 873d7b98d..e786bcbe5 100644 --- a/data/web/lang/lang.en-gb.json +++ b/data/web/lang/lang.en-gb.json @@ -929,7 +929,6 @@ "filters": "Filters", "fname": "Full name", "force_pw_update": "Force password update at next login", - "force_tfa": "TFA", "gal": "Global Address List", "goto_ham": "Learn as ham", "goto_spam": "Learn as spam", @@ -1087,7 +1086,7 @@ "rspamd_result": "Rspamd result", "sender": "Sender (SMTP)", "sender_header": "Sender (\"From\" header)", - "settings_info": "Maximum amount of elements to be quarantined (per mailbox): %s
Maximum email size: %s MiB", + "settings_info": "Maximum amount of elements to be quarantined: %s
Maximum email size: %s MiB", "show_item": "Show item", "spam": "Spam", "spam_score": "Score", diff --git a/data/web/lang/lang.fr-fr.json b/data/web/lang/lang.fr-fr.json index 9ee916713..43c9c065a 100644 --- a/data/web/lang/lang.fr-fr.json +++ b/data/web/lang/lang.fr-fr.json @@ -111,8 +111,7 @@ "app_passwd_protocols": "Protocoles autorisés pour le mot de passe de l'application", "dry": "Simuler la synchronisation", "internal": "Interne", - "internal_info": "Les alias internes sont accessibles uniquement depuis le domaine ou les alias du domaine.", - "sender_allowed": "Autoriser l'envoi sous cet alias" + "internal_info": "Les alias internes sont accessibles uniquement depuis le domaine ou les alias du domaine." }, "admin": { "access": "Accès", @@ -557,9 +556,7 @@ "max_age_invalid": "L'âge maximum %s est invalide", "mode_invalid": "Le mode %s est invalide", "mx_invalid": "L'enregistrement MX %s est invalide", - "version_invalid": "La version %s est invalide", - "tfa_removal_blocked": "L’authentification à deux facteurs ne peut pas être supprimée, car elle est requise pour votre compte.", - "quarantine_category_invalid": "La catégorie de quarantaine doit être l’une des suivantes : add_header, reject, all\"" + "version_invalid": "La version %s est invalide" }, "debug": { "chart_this_server": "Graphique (ce serveur)", @@ -758,9 +755,7 @@ "mta_sts_info": "
MTA-STS est un standard qui oblige la délivrance des courriels entre les serveurs de courriels à utiliser TLS avec des certificats valides.
Il est utilisé quand DANE n'est pas possible à cause d'un manque ou d'un non support de DNSSEC.
Note : Si le domaine du destinataire supporte DANE avec DNSSEC, DANE est toujours préféré – MTA-STS sert seulement en secours.", "mta_sts_mode_info": "Il y a trois modes parmi lesquels choisir :
  • testing – la politique est seulement surveillée, les violations n'ont pas d'impact.
  • enforce – la politique est appliquée strictement, les connexions sans TLS valide sont rejetées.
  • none – la politique est publiée mais non appliquée.
", "mta_sts_max_age_info": "Durée en secondes pendant laquelle les serveurs de courriel peuvent mettre en cache cette politique avant de revérifier.", - "mta_sts_mx_info": "Autoriser l'envoi uniquement aux noms d'hôtes des serveurs de courriels indiqués explicitement ; le MTA émetteur vérifie si le nom d'hôte DNS du MX correspond à la liste de la politique, et autorise la délivrance seulement avec un certificat TLS valide (protège contre le MITM).", - "sender_allowed": "Autoriser l'envoi sous cet alias", - "sender_allowed_info": "Si cette option est désactivée, cet alias peut uniquement recevoir des courriels. Utilisez les ACL d’expéditeur pour autoriser certaines boîtes aux lettres à envoyer des messages via cet alias." + "mta_sts_mx_info": "Autoriser l'envoi uniquement aux noms d'hôtes des serveurs de courriels indiqués explicitement ; le MTA émetteur vérifie si le nom d'hôte DNS du MX correspond à la liste de la politique, et autorise la délivrance seulement avec un certificat TLS valide (protège contre le MITM)." }, "footer": { "cancel": "Annuler", @@ -993,8 +988,7 @@ "recipient": "Destinataire", "open_logs": "Afficher les journaux", "iam": "Fournisseur d'identité", - "internal": "Interne", - "force_tfa": "TFA" + "internal": "Interne" }, "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.", @@ -1195,11 +1189,7 @@ "yubi_otp": "Authentification OTP Yubico", "authenticators": "Authentificateurs", "u2f_deprecated_important": "Veuillez enregistrer votre clé dans le panneau d'administration avec la nouvelle méthode WebAuthn.", - "u2f_deprecated": "Il semble que votre clé ait été enregistrée à l'aide de la méthode U2F obsolète. Nous allons désactiver l'authentification à deux facteurs pour vous et supprimer votre clé.", - "force_tfa": "Imposer l'authentification à deux facteurs lors de la connexion", - "force_tfa_info": "L’utilisateur doit configurer l’authentification à deux facteurs avant de pouvoir accéder à l’interface.", - "setup_title": "Authentification à deux facteurs requise", - "setup_required": "Votre compte nécessite l’authentification à deux facteurs. Veuillez configurer une méthode 2FA pour continuer." + "u2f_deprecated": "Il semble que votre clé ait été enregistrée à l'aide de la méthode U2F obsolète. Nous allons désactiver l'authentification à deux facteurs pour vous et supprimer votre clé." }, "fido2": { "set_fn": "Définir un nom", @@ -1388,8 +1378,7 @@ "forever": "Pour toujours", "spam_aliases_info": "Un alias de spam est une adresse de courriel temporaire qui peut être utilisée pour protéger les véritables adresses de courriel.
De manière optionnelle, une durée d'expiration peut être définie afin que l'alias soit automatiquement désactivé après la période définie, éliminant ainsi les adresses étant abusées ou ayant fuité.", "authentication": "Authentification", - "protocols": "Protocoles", - "pw_update_required": "Votre compte nécessite un changement de mot de passe. Veuillez définir un nouveau mot de passe pour continuer." + "protocols": "Protocoles" }, "warning": { "cannot_delete_self": "Impossible de supprimer l’utilisateur connecté", diff --git a/data/web/lang/lang.lv-lv.json b/data/web/lang/lang.lv-lv.json index df1697282..fd29e594a 100644 --- a/data/web/lang/lang.lv-lv.json +++ b/data/web/lang/lang.lv-lv.json @@ -13,7 +13,7 @@ "domain_relayhost": "Mainīt domēna relayhost", "eas_reset": "EAS ierīču atiestatīšana", "extend_sender_acl": "Ļauj paplašināt sūtītāja ACL ar ārējām adresēm", - "login_as": "Pieteikties kā pastkastes lietotājam", + "login_as": "Pieteikšanās kā pastkastes lietotājam", "mailbox_relayhost": "Pasta kastītes relayhost maiņa", "prohibited": "Aizliegts ar ACL", "protocol_access": "Protokola piekļuves maiņa", @@ -91,12 +91,12 @@ "activate_api": "Aktivizēt API", "active": "Aktīvs", "add": "Pievienot", - "add_domain_admin": "Pievienot domēna pārvaldītāju", + "add_domain_admin": "Pievienot domēna administratoru", "add_forwarding_host": "Pievienot pāradresācijas hostu", "add_relayhost": "Pievienot Relayhost", "add_row": "Pievienot rindu", - "admin": "Pārvaldītājs", - "admin_details": "Labot informāciju par pārvaldītāju", + "admin": "Administrators", + "admin_details": "Labot administratora detaļas", "admin_domains": "Domēna uzdevumi", "api_allow_from": "Atļaut API piekļuvi no šīm IP", "api_key": "API atslēga", @@ -114,7 +114,7 @@ "dkim_keys": "ARC/DKIM atslēgas", "dkim_private_key": "Privāta atslēga", "domain": "Domēns", - "domain_admins": "Domēna pārvaldītāji", + "domain_admins": "Domēna administratori", "edit": "Labot", "empty": "Nav iznākuma", "f2b_ban_time": "Aizlieguma laiks (s)", @@ -188,14 +188,7 @@ "quarantine_max_score": "Atmest paziņojumu, ja e-pasta ziņojuma mēstuļu novērtējums ir augstāks par šo vērtību:
Noklusējums ir 9999.0", "options": "Iespējas", "password_reset_settings": "Paroļu atkopes iestatījumi", - "password_settings": "Paroļu iestatījumi", - "add_admin": "Pievienot pārvaldītāju", - "admins": "Pārvaldītāji", - "admins_ldap": "LDAP pārvaldītāji", - "admin_quicklink": "Paslēpt ātro saiti uz pārvaldītāju pieteikšanās lapu", - "domain_admin": "Domēna pārvaldītājs", - "domainadmin_quicklink": "Paslēpt ātro saiti uz domēna pārvaldītāju pieteikšanās lapu", - "user_quicklink": "Paslēpt ātro saiti uz lietotāju pieteikšanās lapu" + "password_settings": "Paroļu iestatījumi" }, "danger": { "access_denied": "Piekļuve liegta, vai nepareizi dati", @@ -251,10 +244,7 @@ "app_passwd_id_invalid": "Lietotnes paroles Id %s ir nederīgs", "img_dimensions_exceeded": "Attēls pārsniedz lielāko pieļaujamo attēla lielumu", "img_size_exceeded": "Attēls pārsniedz lielāko pieļaujamo datnes lielumu", - "version_invalid": "Versija %s ir nederīga", - "generic_server_error": "Atgadījās neparedzēta servera kļūda. Lūgums sazināties ar pārvaldītāju.", - "password_reset_na": "Paroļu atkope šobrīd nav pieejama. Lūgums sazināties ar pārvaldītāju.", - "recovery_email_failed": "Nevarēja nosūtīt atkopes e-pasta ziņojumu. Lūgums sazināties ar pārvaldītāju." + "version_invalid": "Versija %s ir nederīga" }, "diagnostics": { "cname_from_a": "Vērtība, kas iegūta no A/AAAA ieraksta. Tas tiek atbalstīts tik ilgi, kamēr ieraksts norāda uz pareizo resursu.", @@ -276,7 +266,7 @@ "delete2duplicates": "Izdzēst atkārtojošos vienumus galamērķī", "description": "Apraksts", "domain": "Labot domēnu", - "domain_admin": "Labot domēna pārvaldītāju", + "domain_admin": "Labot domēna administratoru", "domain_quota": "Domēna kvota", "domains": "Domēni", "dont_check_sender_acl": "Atspējot sūtītāju pārbaudi domēnam %s (+ aizstājdomēni)", @@ -339,8 +329,7 @@ "app_passwd": "Lietotnes parole", "mta_sts_version": "Versija", "mta_sts_version_info": "Norāda MTA-STS standarta versiju – pašreiz ir derīga tikai STSv1.", - "sender_acl_disabled": "Sūtītāja pārbaude ir atspējota", - "admin": "Labot pārvaldītāju" + "sender_acl_disabled": "Sūtītāja pārbaude ir atspējota" }, "footer": { "cancel": "Atcelt", @@ -373,14 +362,7 @@ "username": "Lietotājvārds", "fido2_webauthn": "FIDO/WebAuthn pieteikšanās", "mobileconfig_info": "Lūgums pieteikties kā pastkastes lietotājam, lai lejupielādētu pieprasīto Apple savienojuma profilu.", - "other_logins": "vai pieteikties ar", - "forgot_password": "> Aizmirsta parole?", - "login_linkstext": "Nepareiza pieteikšanās?", - "login_domainadmintext": "Pieteikties kā domēna pārvaldītājam", - "login_admintext": "Pieteikties kā pārvaldītājam", - "login_user": "Lietotu pieteikšanās", - "login_dadmin": "Domēna pārvaldītāju pieteikšanās", - "login_admin": "Pārvaldītāju pieteikšanās" + "other_logins": "vai pieslēgties ar" }, "mailbox": { "action": "Rīcība", @@ -415,7 +397,7 @@ "description": "Apraksts", "dkim_key_length": "DKIM atslēgas garums (bits)", "domain": "Domēns", - "domain_admins": "Domēna pārvaldītāji", + "domain_admins": "Domēna administratori", "domain_aliases": "Domēna aizstājvārdi", "domain_quota": "Kvota", "domain_quota_total": "Kopējais domēna ierobežojums", @@ -525,7 +507,7 @@ "imap_smtp_server_auth_info": "Lūgums izmantot pilnu e-pasta adresi un PLAIN autentificēšanās mehānismu.
\nPieteikšanās dati tiks šifrēti ar servera puses obligātu šifrēšanu." }, "success": { - "admin_modified": "Pārvaldītāja izmaiņas tika saglabātas", + "admin_modified": "Izmaiņas administrātoram ir saglabātas", "alias_added": "Aizstājadrese %s (%d) tika pievienota", "alias_domain_removed": "Aizstājdomēns %s tika noņemts", "alias_modified": "Aizstājadreses izmaiņas %s tika saglabātas", @@ -536,9 +518,9 @@ "dkim_added": "DKIM atslēga saglabāta", "dkim_removed": "DKIM atslēga %s ir noņemta", "domain_added": "Pievienots domēns %s", - "domain_admin_added": "Tika pievienots domēna pārvaldītājs %s", - "domain_admin_modified": "Domēna pārvaldītāja %s izmaiņas tika saglabātas", - "domain_admin_removed": "Tika noņemts domēna pārvaldītājs %s", + "domain_admin_added": "Domēna administrātors %s pievienots", + "domain_admin_modified": "Izmaiņas domēna administrātoram %s ir saglabātas", + "domain_admin_removed": "Domēna administrators %s tika noņemts", "domain_modified": "Izmaiņas domēnam %s ir saglabātas", "domain_removed": "Domēns %s ir noņemts", "eas_reset": "ActiveSync ierīces priekš lietotāja %s tika atiestatītas", @@ -566,9 +548,7 @@ "verified_yotp_login": "Apliecināta Yubico OTP pieteikšanās", "app_passwd_removed": "Noņemta lietotnes parole ar Id %s", "app_passwd_added": "Pievienota jauna lietotnes parole", - "f2b_banlist_refreshed": "Liegumu saraksta Id tika sekmīgi atsvaidzināts.", - "admin_added": "Tika pievienots pārvaldītājs %s", - "admin_removed": "Tika noņemts pārvaldītājs %s" + "f2b_banlist_refreshed": "Liegumu saraksta Id tika sekmīgi atsvaidzināts." }, "tfa": { "api_register": "%s izmanto Yubico Cloud API. Lūdzu iegūstiet API atslēgu priekš Jūsu atslēgashere", @@ -589,8 +569,7 @@ "waiting_usb_auth": "Gaida USB ierīci...

Lūdzu, tagad nospiežiet pogu uz Jūsu WebAuthn USB ierīces.", "waiting_usb_register": "Gaida USB ierīci...

Lūgums augstāk ievadīt savu paroli un apstiprināt reģistrēšanos ar USB ierīces pogas nospiešanu.", "yubi_otp": "Yubico OTP autentifikators", - "authenticators": "Autentificētāji", - "u2f_deprecated_important": "Lūgums reģistrēt savu atslēgu pārvaldības lapā ar jauno WebAuthn veidu." + "authenticators": "Autentificētāji" }, "user": { "action": "Rīcība", @@ -722,8 +701,7 @@ "warning": { "domain_added_sogo_failed": "Domēns pievienots, bet neizdevās pārsāknēt SOGO. Lūgums pārbaudīt servera žurnālus.", "dovecot_restart_failed": "Dovecot neizdevās pārsāknēties. Lūgums pārbaudīt žurnālus", - "is_not_primary_alias": "Izlaists aizstājvārds %s, kas nav galvenais", - "no_active_admin": "Nevar deaktivēt pēdējo aktīvo pārvaldītāju" + "is_not_primary_alias": "Izlaists aizstājvārds %s, kas nav galvenais" }, "oauth2": { "access_denied": "Lūgums pieteikties kā pastkastes īpašniekam, lai nodrošinātu piekļuvi ar OAuth2." diff --git a/data/web/lang/lang.pl-pl.json b/data/web/lang/lang.pl-pl.json index de3557c03..b1ec3591c 100644 --- a/data/web/lang/lang.pl-pl.json +++ b/data/web/lang/lang.pl-pl.json @@ -189,7 +189,7 @@ "api_info": "API jest w trakcie prac. Dokumentację można znaleźć pod adresem /api", "api_key": "klucz API", "api_read_only": "Dostęp tylko do odczytu", - "api_read_write": "Dostęp do odczytu i zapisu", + "api_read_write": "Dostęp tylko do odczytu", "api_skip_ip_check": "Pomiń sprawdzenie IP dla API", "app_hide": "Ukryj dla logowania", "app_links": "Linki aplikacji", diff --git a/data/web/lang/lang.si-si.json b/data/web/lang/lang.si-si.json index 39d57eb31..f5ba53f98 100644 --- a/data/web/lang/lang.si-si.json +++ b/data/web/lang/lang.si-si.json @@ -1001,8 +1001,7 @@ "weekly": "Tedensko", "sieve_info": "Na uporabnika lahko shranite več filtrov, vendar je lahko hkrati aktiven le en predfilter in en postfilter.
\nVsak filter bo obdelan v opisanem vrstnem redu. Niti neuspešen skript niti izdan ukaz »keep;« ne bosta ustavila obdelave nadaljnjih skript. Spremembe globalnih skriptov sita bodo sprožile ponovni zagon Dovecota.

Globalni predfilter sita • Predfilter • Uporabniški skripti • Postfilter • Globalni postfilter sita", "tls_policy_maps_info": "Ta preslikava pravilnikov preglasi pravila odhodnega prenosa TLS neodvisno od uporabnikovih nastavitev pravilnikov TLS.
\n Za več informacij preverite dokumentacijo »smtp_tls_policy_maps«.", - "internal": "Notranje", - "force_tfa": "TFA" + "internal": "Notranje" }, "fido2": { "known_ids": "Znani ID-ji", diff --git a/data/web/lang/lang.vi-vn.json b/data/web/lang/lang.vi-vn.json index 42813fd25..523b5dca9 100644 --- a/data/web/lang/lang.vi-vn.json +++ b/data/web/lang/lang.vi-vn.json @@ -268,10 +268,10 @@ "includes": "Bao gồm những người nhận này", "ip_check": "Kiểm tra IP", "ip_check_disabled": "Kiểm tra IP đã bị vô hiệu hóa. Bạn có thể bật nó trong
Hệ thống > Cấu hình > Tùy chọn > Tùy chỉnh", - "ip_check_opt_in": "Đăng ký tham gia sử dụng dịch vụ bên thứ ba dùng ipv4.mailcow.emailipv6.mailcow.email để phân giải địa chỉ IP bên ngoài.", + "ip_check_opt_in": "Chọn tham gia sử dụng dịch vụ bên thứ ba ipv4.mailcow.emailipv6.mailcow.email để phân giải địa chỉ IP bên ngoài.", "is_mx_based": "Dựa trên MX", "last_applied": "Áp dụng lần cuối", - "license_info": "Giấy phép tuy không bắt buộc nhưng giúp phát triển thêm.
Đăng ký GUID của bạn tại đây hoặc mua hỗ trợ cho cài đặt mailcow của bạn.", + "license_info": "Giấy phép không bắt buộc nhưng giúp phát triển thêm.
Đăng ký GUID của bạn tại đây hoặc mua hỗ trợ cho cài đặt mailcow của bạn.", "link": "Liên kết", "loading": "Vui lòng đợi...", "login_time": "Thời gian đăng nhập", @@ -556,9 +556,7 @@ "validity_missing": "Vui lòng gán thời hạn hiệu lực", "value_missing": "Vui lòng cung cấp tất cả các giá trị", "version_invalid": "Phiên bản %s không hợp lệ", - "yotp_verification_failed": "Xác thực Yubico OTP thất bại: %s", - "tfa_removal_blocked": "Xác thực hai yếu tố không thể bị xóa vì đây là yêu cầu bắt buộc đối với tài khoản của bạn.", - "quarantine_category_invalid": "Danh mục cách ly phải là một trong các loại sau : add_header, reject, all." + "yotp_verification_failed": "Xác thực Yubico OTP thất bại: %s" }, "datatables": { "collapse_all": "Thu gọn tất cả", @@ -581,9 +579,7 @@ "aria": { "sortAscending": ": kích hoạt để sắp xếp cột tăng dần", "sortDescending": ": kích hoạt để sắp xếp cột giảm dần" - }, - "decimal": ".", - "thousands": "," + } }, "debug": { "architecture": "Kiến trúc", @@ -697,19 +693,6 @@ "internal_info": "Bí danh nội bộ chỉ có thể truy cập từ tên miền sở hữu hoặc tên miền bí danh.", "kind": "Loại", "last_modified": "Sửa đổi lần cuối", - "lookup_mx": "Đích là một biểu thức chính quy để khớp với tên MX (.*.google.com để định tuyến tất cả thư nhắm đến MX kết thúc bằng google.com qua bước nhảy này)", - "sender_allowed": "Cho phép gửi đi bằng bí danh", - "sender_allowed_info": "Nếu bị vô hiệu hóa, bí danh này chỉ có thể nhận thư. Sử dụng ACL của người gửi để ghi đè và cấp quyền gửi cho các hộp thư cụ thể.", - "mailbox": "Chỉnh sửa hộp thư", - "mailbox_quota_def": "Hạn mức hộp thư mặc định", - "mailbox_relayhost_info": "Chỉ áp dụng cho hộp thư và các bí danh trực tiếp, thao tác này sẽ ghi đè lên máy chủ chuyển tiếp tên miền.", - "mailbox_rename": "Đổi tên hộp thư", - "mailbox_rename_agree": "Tôi đã tạo bản sao lưu.", - "mailbox_rename_warning": "QUAN TRỌNG! Hãy tạo bản sao lưu trước khi đổi tên hộp thư.", - "mailbox_rename_alias": "Tạo tự động bí danh", - "mailbox_rename_title": "Tên mới của hộp thư cục bộ", - "max_aliases": "Số lượng Bí danh tối đa", - "max_mailboxes": "Số lượng hộp thư tối đa có thể có", - "max_quota": "Dung lượng tối đa cho mỗi hộp thư (MiB)" + "lookup_mx": "Đích là một biểu thức chính quy để khớp với tên MX (.*.google.com để định tuyến tất cả thư nhắm đến MX kết thúc bằng google.com qua bước nhảy này)" } } diff --git a/data/web/mobileconfig.php b/data/web/mobileconfig.php index c57c48857..7c0ead7f5 100644 --- a/data/web/mobileconfig.php +++ b/data/web/mobileconfig.php @@ -65,7 +65,6 @@ if (isset($_GET['app_password'])) { $attr['protocols'][] = 'dav_access'; } app_passwd("add", $attr); - $password = htmlspecialchars($password, ENT_NOQUOTES); } else { $app_password = false; } diff --git a/data/web/templates/edit/mailbox-templates.twig b/data/web/templates/edit/mailbox-templates.twig index 8384fa053..ddc139586 100644 --- a/data/web/templates/edit/mailbox-templates.twig +++ b/data/web/templates/edit/mailbox-templates.twig @@ -8,7 +8,6 @@ - @@ -166,14 +165,6 @@ -
-
-
- - {{ lang.tfa.force_tfa_info }} -
-
-
{% if not skip_sogo %}
diff --git a/docker-compose.yml b/docker-compose.yml index 30a7ba96b..eab23c8a0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ services: unbound-mailcow: - image: ghcr.io/mailcow/unbound:1.25.1-1 + image: ghcr.io/mailcow/unbound:1.25 environment: - TZ=${TZ} - SKIP_UNBOUND_HEALTHCHECK=${SKIP_UNBOUND_HEALTHCHECK:-n} @@ -84,7 +84,7 @@ services: - clamd rspamd-mailcow: - image: ghcr.io/mailcow/rspamd:4.1.0-1 + image: ghcr.io/mailcow/rspamd:3.14.3-1 stop_grace_period: 30s depends_on: - dovecot-mailcow @@ -117,7 +117,7 @@ services: - rspamd php-fpm-mailcow: - image: ghcr.io/mailcow/phpfpm:8.2.29-3 + image: ghcr.io/mailcow/phpfpm:8.2.29-2 command: "php-fpm -d date.timezone=${TZ} -d expose_php=0" depends_on: - redis-mailcow @@ -200,7 +200,7 @@ services: - phpfpm sogo-mailcow: - image: ghcr.io/mailcow/sogo:5.12.9-1 + image: ghcr.io/mailcow/sogo:5.12.8-1 environment: - DBNAME=${DBNAME} - DBUSER=${DBUSER} @@ -339,7 +339,7 @@ services: - dovecot postfix-mailcow: - image: ghcr.io/mailcow/postfix:3.10.12-1 + image: ghcr.io/mailcow/postfix:3.7.11-2 depends_on: mysql-mailcow: condition: service_started @@ -419,7 +419,7 @@ services: - php-fpm-mailcow - sogo-mailcow - rspamd-mailcow - image: ghcr.io/mailcow/nginx:1.30.3-1 + image: ghcr.io/mailcow/nginx:1.30.1-1 dns: - ${IPV4_NETWORK:-172.22.1}.254 environment: diff --git a/helper-scripts/docker-compose.override.yml.d/EXTERNAL_MYSQL_SOCKET/docker-compose.override.yml b/helper-scripts/docker-compose.override.yml.d/EXTERNAL_MYSQL_SOCKET/docker-compose.override.yml index fd47e15fe..5ef729a48 100644 --- a/helper-scripts/docker-compose.override.yml.d/EXTERNAL_MYSQL_SOCKET/docker-compose.override.yml +++ b/helper-scripts/docker-compose.override.yml.d/EXTERNAL_MYSQL_SOCKET/docker-compose.override.yml @@ -25,6 +25,6 @@ services: - /var/run/mysqld/mysqld.sock:/var/run/mysqld/mysqld.sock mysql-mailcow: - image: alpine:3.24 + image: alpine:3.23 command: /bin/true restart: "no"