From ddcce811c1f77658d857ec3357505eba1fce264d Mon Sep 17 00:00:00 2001 From: Chris Haumesser <5400416-wryfi@users.noreply.gitlab.com> Date: Fri, 12 Jun 2026 16:32:22 -0600 Subject: [PATCH 01/17] Fixes #7150 (Dovecot passwd-verify.lua wipes auth cache during any nginx restart or unavailability) - distinguishes between text and numeric responses from nginx - prevents auth cache from being invalidated due to nginx unavailability --- data/conf/dovecot/auth/passwd-verify.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/data/conf/dovecot/auth/passwd-verify.lua b/data/conf/dovecot/auth/passwd-verify.lua index ea847932d..a22488ea8 100644 --- a/data/conf/dovecot/auth/passwd-verify.lua +++ b/data/conf/dovecot/auth/passwd-verify.lua @@ -32,8 +32,17 @@ function auth_password_verify(request, password) -- Returning PASSDB_RESULT_PASSWORD_MISMATCH will reset the user's auth cache entry. -- Returning PASSDB_RESULT_INTERNAL_FAILURE keeps the existing cache entry, -- even if the TTL has expired. Useful to avoid cache eviction during backend issues. + + -- On a network-level failure (nginx unreachable, DNS failure, timeout) https.request + -- returns nil plus an error string, so c is not a numeric HTTP status code. Treat this + -- as a backend outage and keep the cache entry, rather than wiping it as a mismatch. + if type(c) ~= "number" then + dovecot.i_info("HTTP request to auth backend failed with " .. tostring(c) .. " for user " .. request.user) + return dovecot.auth.PASSDB_RESULT_INTERNAL_FAILURE, "Upstream unreachable" + end + if c ~= 200 and c ~= 401 then - dovecot.i_info("HTTP request failed with " .. c .. " for user " .. request.user) + dovecot.i_info("HTTP request failed with " .. tostring(c) .. " for user " .. request.user) return dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH, "Upstream error" end From fffe1aec3d16a2933cbfbbb30ceb8b4a2cd862dd Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Mon, 13 Jul 2026 19:16:10 +0200 Subject: [PATCH 02/17] postfix-tlspol: upgrade to trixie + 1.11.0 update --- data/Dockerfiles/postfix-tlspol/Dockerfile | 6 +++--- data/Dockerfiles/postfix-tlspol/syslog-ng-redis_slave.conf | 4 ++-- data/Dockerfiles/postfix-tlspol/syslog-ng.conf | 4 ++-- docker-compose.yml | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/data/Dockerfiles/postfix-tlspol/Dockerfile b/data/Dockerfiles/postfix-tlspol/Dockerfile index 68f6ecced..fa363845f 100644 --- a/data/Dockerfiles/postfix-tlspol/Dockerfile +++ b/data/Dockerfiles/postfix-tlspol/Dockerfile @@ -1,17 +1,17 @@ -FROM golang:1.25-bookworm AS builder +FROM golang:1.26-trixie AS builder WORKDIR /src ENV CGO_ENABLED=0 \ GO111MODULE=on \ NOOPT=1 \ - VERSION=1.8.22 + VERSION=1.11.0 RUN git clone --branch v${VERSION} https://github.com/Zuplu/postfix-tlspol && \ cd /src/postfix-tlspol && \ scripts/build.sh build-only -FROM debian:bookworm-slim +FROM debian:trixie-slim LABEL maintainer="The Infrastructure Company GmbH " ARG DEBIAN_FRONTEND=noninteractive diff --git a/data/Dockerfiles/postfix-tlspol/syslog-ng-redis_slave.conf b/data/Dockerfiles/postfix-tlspol/syslog-ng-redis_slave.conf index 3862a3547..022dfc3da 100644 --- a/data/Dockerfiles/postfix-tlspol/syslog-ng-redis_slave.conf +++ b/data/Dockerfiles/postfix-tlspol/syslog-ng-redis_slave.conf @@ -1,4 +1,4 @@ -@version: 3.38 +@version: 4.8 @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-tlspol/syslog-ng.conf b/data/Dockerfiles/postfix-tlspol/syslog-ng.conf index 7126c1250..70c92b5c0 100644 --- a/data/Dockerfiles/postfix-tlspol/syslog-ng.conf +++ b/data/Dockerfiles/postfix-tlspol/syslog-ng.conf @@ -1,4 +1,4 @@ -@version: 3.38 +@version: 4.8 @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/docker-compose.yml b/docker-compose.yml index 30a7ba96b..b3cb8bef6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -382,7 +382,7 @@ services: - postfix postfix-tlspol-mailcow: - image: ghcr.io/mailcow/postfix-tlspol:1.8.23 + image: ghcr.io/mailcow/postfix-tlspol:1.11.0 depends_on: unbound-mailcow: condition: service_healthy From 0f06c8e5637ebe2ec1b95d8ef469a1f5a9c803c9 Mon Sep 17 00:00:00 2001 From: DerLinkman Date: Mon, 13 Jul 2026 19:34:58 +0200 Subject: [PATCH 03/17] postfix: prepare TLSRPT compatibility for tlspol --- data/conf/postfix/main.cf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/conf/postfix/main.cf b/data/conf/postfix/main.cf index 080be499a..4329f5487 100644 --- a/data/conf/postfix/main.cf +++ b/data/conf/postfix/main.cf @@ -150,7 +150,7 @@ smtp_sasl_auth_enable = yes smtp_sasl_password_maps = proxy:mysql:/opt/postfix/conf/sql/mysql_sasl_passwd_maps_sender_dependent.cf smtp_sasl_security_options = smtp_sasl_mechanism_filter = plain, login -smtp_tls_policy_maps = proxy:mysql:/opt/postfix/conf/sql/mysql_tls_policy_override_maps.cf socketmap:inet:postfix-tlspol:8642:QUERY +smtp_tls_policy_maps = proxy:mysql:/opt/postfix/conf/sql/mysql_tls_policy_override_maps.cf socketmap:inet:postfix-tlspol:8642:QUERYwithTLSRPT smtp_header_checks = pcre:/opt/postfix/conf/anonymize_headers.pcre mail_name = Postcow # local_transport map catches local destinations and prevents routing local dests when the next map would route "*" From bd5c18b145707b1488411f2dafea8e0603e62047 Mon Sep 17 00:00:00 2001 From: Paul Seebach Date: Sat, 21 Mar 2026 15:54:34 +0100 Subject: [PATCH 04/17] [Web] Add show/hide password toggle on login pages Adds an eye icon button to the password field on the user, admin, and domain admin login pages. Clicking it toggles between hidden and visible password text, using Bootstrap Icons (bi-eye / bi-eye-slash). Closes #6893 --- data/web/templates/admin_index.twig | 1 + data/web/templates/domainadmin_index.twig | 1 + data/web/templates/user_index.twig | 1 + 3 files changed, 3 insertions(+) diff --git a/data/web/templates/admin_index.twig b/data/web/templates/admin_index.twig index 0dcb9145e..12e1b6cda 100644 --- a/data/web/templates/admin_index.twig +++ b/data/web/templates/admin_index.twig @@ -49,6 +49,7 @@
+
diff --git a/data/web/templates/domainadmin_index.twig b/data/web/templates/domainadmin_index.twig index 2fc7bad98..3e76cf2e8 100644 --- a/data/web/templates/domainadmin_index.twig +++ b/data/web/templates/domainadmin_index.twig @@ -49,6 +49,7 @@
+
diff --git a/data/web/templates/user_index.twig b/data/web/templates/user_index.twig index 28eb6389c..2e843e0d7 100644 --- a/data/web/templates/user_index.twig +++ b/data/web/templates/user_index.twig @@ -56,6 +56,7 @@
+
From 5408bc809d4304806fb1a54baf099e0bc9dd9e56 Mon Sep 17 00:00:00 2001 From: Paul Seebach Date: Sat, 21 Mar 2026 15:59:29 +0100 Subject: [PATCH 05/17] [Web] Use input-group-text for password toggle button Replaces btn-outline-secondary with input-group-text so the toggle button border matches the surrounding input group consistently. --- data/web/templates/admin_index.twig | 2 +- data/web/templates/domainadmin_index.twig | 2 +- data/web/templates/user_index.twig | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/web/templates/admin_index.twig b/data/web/templates/admin_index.twig index 12e1b6cda..44b3564cc 100644 --- a/data/web/templates/admin_index.twig +++ b/data/web/templates/admin_index.twig @@ -49,7 +49,7 @@
- +
diff --git a/data/web/templates/domainadmin_index.twig b/data/web/templates/domainadmin_index.twig index 3e76cf2e8..af667756a 100644 --- a/data/web/templates/domainadmin_index.twig +++ b/data/web/templates/domainadmin_index.twig @@ -49,7 +49,7 @@
- +
diff --git a/data/web/templates/user_index.twig b/data/web/templates/user_index.twig index 2e843e0d7..a06cdb3f6 100644 --- a/data/web/templates/user_index.twig +++ b/data/web/templates/user_index.twig @@ -56,7 +56,7 @@
- +
From 4cba4486715c63e3b7727d26a1a92b6465a7619c Mon Sep 17 00:00:00 2001 From: Stephen Ritz <127270018+smpaz7467@users.noreply.github.com> Date: Tue, 14 Jul 2026 15:11:17 -0700 Subject: [PATCH 06/17] [Web] translate password errors in the forced password change modal The forced password change modal posts to the JSON API and renders data[0].msg directly. The API returns raw language keys rather than translated strings, so a user who fails the complexity policy is shown the literal text "password_complexity" instead of a message. Every other password form renders errors through alertbox_log_parser(), which resolves the key against $lang. The modal is the only one that talks to the API directly, and it never resolved the key. Resolve it against lang_danger, which base.twig already exposes for this purpose. This also covers password_mismatch, password_empty and access_denied, and applies to the admin path as well. Unknown keys still fall through unchanged. The lookup is guarded with hasOwnProperty because msg is attacker- independent but dynamic: a bare lang_danger[msg] would resolve inherited Object.prototype members such as "constructor" to a function, which jQuery's .text() would then invoke as a callback. Language files are untouched: prerequisites.inc.php loads lang.en-gb.json as the base and merges the active locale over it, so locales that lack the key inherit the English string. Fixes #7301 Co-Authored-By: Claude Opus 4.8 (1M context) --- data/web/templates/base.twig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/data/web/templates/base.twig b/data/web/templates/base.twig index 9e20b08a5..e0f3b5b35 100644 --- a/data/web/templates/base.twig +++ b/data/web/templates/base.twig @@ -473,6 +473,10 @@ function recursiveBase64StrToArrayBuffer(obj) { window.location.reload(); } else { var msg = (data && data[0] && data[0].msg) ? data[0].msg : 'Password change failed.'; + // the API returns raw language keys, resolve them like the alert box does + if (Object.prototype.hasOwnProperty.call(lang_danger, msg)) { + msg = lang_danger[msg]; + } $('#changePWAlert').show().text(msg); } }, From e5d0ed8c4c092f8a63b697c41e2f5408b9267028 Mon Sep 17 00:00:00 2001 From: Stephen Ritz <127270018+smpaz7467@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:33:46 -0700 Subject: [PATCH 07/17] [Web] use absolute RHS names in generated DNS zonefile The DNS overview "Download" produces a $ORIGIN zonefile, but the right-hand side of MX, CNAME and SRV records was emitted as a relative name. A target such as mail.example.net is then read relative to the origin and expands to mail.example.net.example.org., which is wrong. The only prior attempt at making names absolute was str_replace($domain, $domain . '.', ...), which appended a dot only to targets that happened to contain the origin domain, so cross-domain targets stayed relative. That same replace also corrupted any TXT value containing the origin (e.g. a DMARC rua=mailto:x@example.org became ...@example.org.). Absolutize the RHS per record type at export time only: MX and CNAME targets, and the SRV target token, get a trailing dot; ports, the SRV root target ".", IP addresses and TXT character strings are left as is. The records used for the on-page DNS validation are untouched, so matching against dns_get_record() output still works. Fixes #6984 Co-Authored-By: Claude Opus 4.8 (1M context) --- data/web/inc/ajax/dns_diagnostics.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/data/web/inc/ajax/dns_diagnostics.php b/data/web/inc/ajax/dns_diagnostics.php index 95e34e886..1987a88cd 100644 --- a/data/web/inc/ajax/dns_diagnostics.php +++ b/data/web/inc/ajax/dns_diagnostics.php @@ -442,6 +442,16 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm unset($record); + // Make a hostname RHS absolute so it is not read relative to $ORIGIN. + // Already-absolute names, the SRV root target "." and IP addresses are left alone. + $absolutize = function($host) { + $host = trim($host); + if ($host === '' || $host === '.' || substr($host, -1) === '.' || filter_var($host, FILTER_VALIDATE_IP)) { + return $host; + } + return $host . '.'; + }; + $dns_data = sprintf("\$ORIGIN %s.\n", $domain); foreach ($records as $record) { if ($domain == substr($record[0], -strlen($domain))) { @@ -462,16 +472,26 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm $val = str_replace(state_optional, '', $val); $val = str_replace(state_good, '', $val); if (strlen($val) > 0) { + // these are all TXT values, their RHS is a character string, not a name $vals[] = sprintf("%s\tIN\t%s\t%s\n", $label, $record[1], $val); } } } else { + if ($record[1] == 'MX' || $record[1] == 'CNAME') { + $val = $absolutize($val); + } + elseif ($record[1] == 'SRV') { + // format here is "target port"; only the target is a name + $parts = explode(' ', $val, 2); + $parts[0] = $absolutize($parts[0]); + $val = implode(' ', $parts); + } $vals[] = sprintf("%s\tIN\t%s\t%s\n", $label, $record[1], $val); } foreach ($vals as $val) { - $dns_data .= str_replace($domain, $domain . '.', $val); + $dns_data .= $val; } } } From 90ca1bf25ac356e02525f33a1c4ecc8980fadc03 Mon Sep 17 00:00:00 2001 From: Stephen Ritz <127270018+smpaz7467@users.noreply.github.com> Date: Tue, 14 Jul 2026 16:39:19 -0700 Subject: [PATCH 08/17] [Web] redirect deep links to the matching login page An unauthenticated request to a deep link such as /admin/dashboard was redirected to /, the user login, instead of the admin login. protect_route always sent unauthenticated visitors to /. Pick the login page from the request path: /admin/* redirects to /admin, /domainadmin/* to /domainadmin, everything else to / as before. Fixes #7284 Co-Authored-By: Claude Opus 4.8 (1M context) --- data/web/inc/functions.inc.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 89f14b574..a796f1587 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -3503,7 +3503,16 @@ function protect_route($allowed_roles = ['admin', 'domainadmin', 'user'], $redir if (isset($redirects['unauthenticated'])) { header('Location: ' . $redirects['unauthenticated']); } else { - header('Location: /'); + // Send a deep link to the login page for its area instead of the user login at /, + // e.g. /admin/dashboard -> /admin rather than / + $request_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/'; + if (strpos($request_uri, '/admin/') === 0) { + header('Location: /admin'); + } elseif (strpos($request_uri, '/domainadmin/') === 0) { + header('Location: /domainadmin'); + } else { + header('Location: /'); + } } exit(); } From 9cd16f00019f96d5e202db07a36e1e8161baf048 Mon Sep 17 00:00:00 2001 From: Stephen Ritz <127270018+smpaz7467@users.noreply.github.com> Date: Tue, 28 Jul 2026 07:12:17 -0700 Subject: [PATCH 09/17] [Web] show external sender addresses regardless of authsource The extended_sender_acl field sat inside the `{% if not result.authsource or result.authsource == 'mailcow' %}` block that hides the local password fields for mailboxes authenticating against an external identity provider. As a result the "External sender addresses" input was not rendered at all for keycloak / generic-oidc / ldap mailboxes, even for a full admin, so those addresses could neither be reviewed nor edited in the UI while the underlying sender_acl rows stayed active. Extended sender ACLs are unrelated to local password management. Move the field out of that block; it stays gated by acl.extend_sender_acl as intended. Fixes #7365 --- data/web/templates/edit/mailbox.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/web/templates/edit/mailbox.twig b/data/web/templates/edit/mailbox.twig index 34e869ce1..db258fe49 100644 --- a/data/web/templates/edit/mailbox.twig +++ b/data/web/templates/edit/mailbox.twig @@ -267,6 +267,7 @@ {{ lang.admin.password_reset_info }}
+ {% endif %}
@@ -279,7 +280,6 @@ {% endif %}
- {% endif %}
From 8bd9e12a73ec68945db9e12f8af406b863d9e2d8 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it <75116288+FreddleSpl0it@users.noreply.github.com> Date: Tue, 18 Aug 2026 14:07:37 +0200 Subject: [PATCH 10/17] [Web] Add ACL + global switch to disable external alias goto --- data/web/inc/functions.inc.php | 12 ++++++++++++ data/web/inc/functions.mailbox.inc.php | 25 +++++++++++++++++++++++++ data/web/inc/init_db.inc.php | 5 +++-- data/web/inc/vars.inc.php | 4 ++++ data/web/lang/lang.de-de.json | 2 ++ data/web/lang/lang.en-gb.json | 2 ++ 6 files changed, 48 insertions(+), 2 deletions(-) diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 90c830b69..a08e39b55 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -633,6 +633,18 @@ function logger($_data = false) { return true; } } +function is_local_mailcow_domain($domain) { + // True if domain is a locally managed, active primary or alias domain + global $pdo; + $domain = idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46); + if (empty($domain)) { + return false; + } + $stmt = $pdo->prepare("SELECT 1 FROM `domain` WHERE `domain` = :d AND `active` = 1 + UNION SELECT 1 FROM `alias_domain` WHERE `alias_domain` = :d2 AND `active` = 1 LIMIT 1"); + $stmt->execute(array(':d' => $domain, ':d2' => $domain)); + return (bool)$stmt->fetchColumn(); +} function hasDomainAccess($username, $role, $domain) { global $pdo; if (empty($domain) || !is_valid_domain_name($domain)) { diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index acbbb94d4..37ccbd85c 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -750,6 +750,18 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { $goto_domain = idn_to_ascii(substr(strstr($goto, '@'), 1), 0, INTL_IDNA_VARIANT_UTS46); $goto_local_part = strstr($goto, '@', true); $goto = $goto_local_part.'@'.$goto_domain; + // Deny external goto domains: global switch (all roles) overrides the per-DA ACL + if (($GLOBALS['ALIAS_DISABLE_EXTERNAL_DOMAINS'] === true || + (isset($_SESSION['acl']['alias_external_goto']) && $_SESSION['acl']['alias_external_goto'] != "1")) && + !is_local_mailcow_domain($goto_domain)) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => array('external_goto_denied', htmlspecialchars($goto)) + ); + unset($gotos[$i]); + continue; + } $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `username`= :goto"); @@ -2715,6 +2727,19 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) { unset($gotos[$i]); continue; } + // Deny external goto domains: global switch (all roles) overrides the per-DA ACL + $goto_domain = idn_to_ascii(substr(strstr($goto, '@'), 1), 0, INTL_IDNA_VARIANT_UTS46); + if (($GLOBALS['ALIAS_DISABLE_EXTERNAL_DOMAINS'] === true || + (isset($_SESSION['acl']['alias_external_goto']) && $_SESSION['acl']['alias_external_goto'] != "1")) && + !is_local_mailcow_domain($goto_domain)) { + $_SESSION['return'][] = array( + 'type' => 'danger', + 'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr), + 'msg' => array('external_goto_denied', htmlspecialchars($goto)) + ); + unset($gotos[$i]); + continue; + } if ($goto == $address) { $_SESSION['return'][] = array( 'type' => 'danger', diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 23aa5e77f..f6b0cd792 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -4,7 +4,7 @@ function init_db_schema() try { global $pdo; - $db_version = "19022026_1220"; + $db_version = "18082026_1200"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -719,7 +719,8 @@ function init_db_schema() "alias_domains" => "TINYINT(1) NOT NULL DEFAULT '0'", "mailbox_relayhost" => "TINYINT(1) NOT NULL DEFAULT '1'", "domain_relayhost" => "TINYINT(1) NOT NULL DEFAULT '1'", - "domain_desc" => "TINYINT(1) NOT NULL DEFAULT '0'" + "domain_desc" => "TINYINT(1) NOT NULL DEFAULT '0'", + "alias_external_goto" => "TINYINT(1) NOT NULL DEFAULT '1'" ), "keys" => array( "primary" => array( diff --git a/data/web/inc/vars.inc.php b/data/web/inc/vars.inc.php index cec402a96..2265c5e1c 100644 --- a/data/web/inc/vars.inc.php +++ b/data/web/inc/vars.inc.php @@ -246,6 +246,10 @@ $PW_RESET_TOKEN_LIMIT = 3; // Maximum time in minutes a password reset token is valid $PW_RESET_TOKEN_LIFETIME = 15; +// Globally forbid aliases with external (non-local) goto domains for ALL roles (incl. admins), +// overriding the per-domain-admin da_acl. false = defer to da_acl. +$ALIAS_DISABLE_EXTERNAL_DOMAINS = false; + // UV flag handling in FIDO2/WebAuthn - defaults to false to allow iOS logins // true = required // false = preferred diff --git a/data/web/lang/lang.de-de.json b/data/web/lang/lang.de-de.json index 28ad0d72b..938f9b929 100644 --- a/data/web/lang/lang.de-de.json +++ b/data/web/lang/lang.de-de.json @@ -1,6 +1,7 @@ { "acl": { "alias_domains": "Alias-Domains hinzufügen", + "alias_external_goto": "Aliase mit externen Ziel-Domains erlauben", "app_passwds": "App-Passwörter verwalten", "bcc_maps": "BCC-Maps", "delimiter_action": "Delimiter-Aktionen (tags)", @@ -443,6 +444,7 @@ "domain_not_found": "Domain %s nicht gefunden", "domain_quota_m_in_use": "Domain-Speicherplatzlimit muss größer oder gleich %d MiB sein", "extended_sender_acl_denied": "Keine Rechte zum Setzen von externen Absenderadressen", + "external_goto_denied": "Externe Ziel-Adresse %s ist nicht erlaubt", "extra_acl_invalid": "Externe Absenderadresse \"%s\" ist ungültig", "extra_acl_invalid_domain": "Externe Absenderadresse \"%s\" verwendet eine ungültige Domain", "fido2_verification_failed": "FIDO2-Verifizierung fehlgeschlagen: %s", diff --git a/data/web/lang/lang.en-gb.json b/data/web/lang/lang.en-gb.json index b8a11e5a5..c958e68eb 100644 --- a/data/web/lang/lang.en-gb.json +++ b/data/web/lang/lang.en-gb.json @@ -1,6 +1,7 @@ { "acl": { "alias_domains": "Add alias domains", + "alias_external_goto": "Allow aliases with external goto domains", "app_passwds": "Manage app passwords", "bcc_maps": "BCC maps", "delimiter_action": "Delimiter action", @@ -444,6 +445,7 @@ "domain_not_found": "Domain %s not found", "domain_quota_m_in_use": "Domain quota must be greater or equal to %s MiB", "extended_sender_acl_denied": "missing ACL to set external sender addresses", + "external_goto_denied": "External goto address %s is not allowed", "extra_acl_invalid": "External sender address \"%s\" is invalid", "extra_acl_invalid_domain": "External sender \"%s\" uses an invalid domain", "fido2_verification_failed": "FIDO2 verification failed: %s", From 7ec61fde8a8bb8cd3c6c8bc449f6c639d605d58d Mon Sep 17 00:00:00 2001 From: milkmaker Date: Wed, 19 Aug 2026 20:23:04 +0200 Subject: [PATCH 11/17] Translations update from Weblate (#7431) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Web] Updated lang.it-it.json Co-authored-by: Claudio * [Web] Updated lang.si-si.json Co-authored-by: Matjaž Tekavec --------- Co-authored-by: Claudio Co-authored-by: Matjaž Tekavec --- data/web/lang/lang.it-it.json | 2 +- data/web/lang/lang.si-si.json | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/data/web/lang/lang.it-it.json b/data/web/lang/lang.it-it.json index a2f0a87e3..267f3b447 100644 --- a/data/web/lang/lang.it-it.json +++ b/data/web/lang/lang.it-it.json @@ -131,7 +131,7 @@ "additional_rows": " righe aggiuntive inserite", "admin": "Amministratore", "admin_details": "Modifica impostazioni amministratore", - "admin_domains": "Assengazioni di dominio", + "admin_domains": "Assegnazioni di dominio", "admins": "Amministratori", "admins_ldap": "Amministratori LDAP", "advanced_settings": "Impostazioni avanzate", diff --git a/data/web/lang/lang.si-si.json b/data/web/lang/lang.si-si.json index 2deb82712..3f88e3611 100644 --- a/data/web/lang/lang.si-si.json +++ b/data/web/lang/lang.si-si.json @@ -785,7 +785,8 @@ "internal": "Notranje", "internal_info": "Notranji vzdevki so dostopni samo iz lastne domene ali vzdevkov domen.", "sender_allowed": "Dovoli pošiljanje kot ta vzdevek", - "sender_allowed_info": "Če je onemogočeno, lahko ta vzdevek samo prejema pošto. Za preglasitev in dodelitev dovoljenja za pošiljanje določenim poštnim predalom uporabite seznam za nadzor dostopa pošiljatelja." + "sender_allowed_info": "Če je onemogočeno, lahko ta vzdevek samo prejema pošto. Za preglasitev in dodelitev dovoljenja za pošiljanje določenim poštnim predalom uporabite seznam za nadzor dostopa pošiljatelja.", + "mta_sts_active_info": "Če ni označeno, pravilnik MTA-STS ne bo objavljen in za poddomeno mta-sts ne bo zahtevano nobeno potrdilo prek ACME." }, "footer": { "restart_container_info": "Pomembno: Eleganten ponovni zagon lahko traja nekaj časa, zato počakajte, da se konča.", From c4d0ca56d28fef84b1d7877eaf2695fa7427bad6 Mon Sep 17 00:00:00 2001 From: milkmaker Date: Tue, 1 Sep 2026 13:07:54 +0200 Subject: [PATCH 12/17] update postscreen_access.cidr (#7450) --- data/conf/postfix/postscreen_access.cidr | 59 +++++++++--------------- 1 file changed, 23 insertions(+), 36 deletions(-) diff --git a/data/conf/postfix/postscreen_access.cidr b/data/conf/postfix/postscreen_access.cidr index 3801fe31e..aa33dd3d8 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 Sat Aug 1 00:35:20 UTC 2026 +# Whitelist generated by Postwhite v3.4 on Tue Sep 1 00:34:07 UTC 2026 # https://github.com/stevejenkins/postwhite/ -# 2256 total rules +# 2243 total rules 2a00:1450:4000::/36 permit 2a00:1450:4864::/56 permit 2a01:111:f400::/48 permit @@ -125,7 +125,6 @@ 23.249.208.0/20 permit 23.251.224.0/19 permit 23.253.141.0/24 permit -23.253.182.0/23 permit 23.253.182.103 permit 23.253.183.145 permit 23.253.183.146 permit @@ -147,24 +146,7 @@ 27.123.206.80/28 permit 31.47.251.17 permit 31.186.239.0/24 permit -34.2.64.0/22 permit -34.2.68.0/23 permit -34.2.70.0/23 permit -34.2.71.64/26 permit -34.2.72.0/22 permit -34.2.75.0/26 permit -34.2.78.0/23 permit -34.2.80.0/23 permit -34.2.82.0/23 permit -34.2.84.0/24 permit -34.2.84.64/26 permit -34.2.85.0/24 permit -34.2.85.64/26 permit -34.2.86.0/23 permit -34.2.88.0/23 permit -34.2.90.0/23 permit -34.2.92.0/23 permit -34.2.94.0/23 permit +34.2.64.0/19 permit 34.70.158.162 permit 34.74.74.140 permit 34.83.159.189 permit @@ -191,6 +173,7 @@ 35.205.92.9 permit 35.228.216.85 permit 35.242.169.159 permit +37.187.220.204 permit 37.188.97.188 permit 37.218.248.47 permit 37.218.249.47 permit @@ -264,8 +247,8 @@ 46.228.39.112/31 permit 46.243.88.174 permit 46.243.88.175 permit -46.243.88.176 permit -46.243.88.177 permit +46.243.88.176/30 permit +46.243.95.96/27 permit 46.243.95.179 permit 46.243.95.180 permit 50.16.246.183 permit @@ -283,6 +266,7 @@ 50.56.130.221 permit 50.56.130.222 permit 50.112.246.219 permit +50.152.146.25 permit 51.83.17.38 permit 52.1.14.157 permit 52.5.230.59 permit @@ -654,6 +638,7 @@ 79.135.106.0/24 permit 79.135.107.0/24 permit 80.225.160.128/25 permit +81.88.38.0/23 permit 81.169.146.243 permit 81.169.146.245 permit 81.169.146.246 permit @@ -738,6 +723,7 @@ 96.43.148.64/28 permit 96.43.148.64/31 permit 96.43.151.64/28 permit +98.77.0.0/16 permit 98.97.248.0/21 permit 98.136.44.181 permit 98.136.44.182/31 permit @@ -1233,8 +1219,6 @@ 104.43.243.237 permit 104.44.112.128/25 permit 104.47.0.0/17 permit -104.130.96.0/28 permit -104.130.122.0/23 permit 106.10.144.64/27 permit 106.10.144.100/31 permit 106.10.144.103 permit @@ -1456,6 +1440,7 @@ 130.35.116.0/25 permit 130.61.9.72 permit 130.162.39.83 permit +130.162.194.23 permit 130.248.172.0/24 permit 130.248.173.0/24 permit 131.186.12.0/25 permit @@ -1539,9 +1524,6 @@ 146.20.14.105 permit 146.20.14.106 permit 146.20.14.107 permit -146.20.112.0/26 permit -146.20.113.0/24 permit -146.20.191.0/24 permit 146.20.215.0/24 permit 146.20.215.182 permit 146.88.28.0/24 permit @@ -1564,10 +1546,11 @@ 149.97.173.180 permit 149.118.160.128/25 permit 150.136.21.199 permit -150.171.109.72 permit +150.171.109.183 permit 150.230.98.160 permit 151.145.38.14 permit 152.67.105.195 permit +152.69.165.251 permit 152.69.200.236 permit 152.70.155.126 permit 155.248.135.128/25 permit @@ -1589,6 +1572,7 @@ 158.247.16.0/20 permit 158.247.100.0/25 permit 159.13.4.0/25 permit +159.13.33.181 permit 159.92.154.0/24 permit 159.92.155.0/24 permit 159.92.157.0/24 permit @@ -1616,6 +1600,8 @@ 159.183.121.182 permit 159.183.129.172 permit 160.1.62.192 permit +161.33.94.110 permit +161.33.228.244 permit 161.38.192.0/20 permit 161.38.204.0/22 permit 161.71.32.0/19 permit @@ -1647,7 +1633,6 @@ 165.173.182.0/24 permit 165.173.182.250/31 permit 165.173.189.205 permit -166.78.68.0/22 permit 166.78.68.221 permit 166.78.69.169 permit 166.78.69.170 permit @@ -1802,9 +1787,9 @@ 188.125.85.234/31 permit 188.125.85.236/31 permit 188.125.85.238 permit -188.165.51.139 permit 188.172.128.0/20 permit 192.0.64.0/18 permit +192.9.166.184 permit 192.18.139.154 permit 192.18.145.36 permit 192.18.152.58 permit @@ -1829,7 +1814,6 @@ 192.30.252.0/22 permit 192.161.144.0/20 permit 192.162.87.0/24 permit -192.237.158.0/23 permit 192.237.159.42 permit 192.237.159.43 permit 192.254.112.0/20 permit @@ -1872,7 +1856,6 @@ 198.21.0.0/21 permit 198.37.144.0/20 permit 198.37.152.186 permit -198.61.254.0/23 permit 198.61.254.21 permit 198.61.254.231 permit 198.178.234.57 permit @@ -1959,6 +1942,7 @@ 204.14.232.0/21 permit 204.14.232.64/28 permit 204.14.234.64/28 permit +204.75.18.128/27 permit 204.75.142.0/24 permit 204.92.114.187 permit 204.92.114.203 permit @@ -1966,7 +1950,9 @@ 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.90.0/23 permit +204.220.92.0/22 permit +204.220.160.0/20 permit 204.220.168.0/21 permit 204.220.176.0/20 permit 204.220.181.105 permit @@ -2002,6 +1988,8 @@ 207.211.31.0/25 permit 207.211.41.113 permit 207.211.132.0/25 permit +207.211.147.87 permit +207.211.159.110 permit 207.218.90.0/24 permit 207.218.90.122 permit 207.250.68.0/24 permit @@ -2051,7 +2039,6 @@ 209.43.22.0/28 permit 209.46.117.168 permit 209.46.117.179 permit -209.61.151.0/24 permit 209.61.151.236 permit 209.61.151.249 permit 209.61.151.251 permit @@ -2238,7 +2225,7 @@ 2001:748:400:3301::4 permit 2404:6800:4000::/36 permit 2404:6800:4864::/56 permit -2603:1061:14:75::1 permit +2603:1061:14:102::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 From b05f59b7058b42c9a6028f48c3c6ecddd1d67391 Mon Sep 17 00:00:00 2001 From: milkmaker Date: Mon, 7 Sep 2026 21:38:12 +0200 Subject: [PATCH 13/17] Translations update from Weblate (#7457) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Web] Updated lang.si-si.json Co-authored-by: Matjaž Tekavec Co-authored-by: milkmaker * [Web] Updated lang.zh-cn.json Co-authored-by: 雨 --------- Co-authored-by: Matjaž Tekavec Co-authored-by: 雨 --- data/web/lang/lang.si-si.json | 6 ++++-- data/web/lang/lang.zh-cn.json | 29 ++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/data/web/lang/lang.si-si.json b/data/web/lang/lang.si-si.json index 3f88e3611..368c0cd12 100644 --- a/data/web/lang/lang.si-si.json +++ b/data/web/lang/lang.si-si.json @@ -29,7 +29,8 @@ "extend_sender_acl": "Dovoli razširitev pošiljateljevega ACL z zunanjimi e-poštnimi naslovi", "quarantine_category": "Spremeni kategorijo obvestil o karanteni", "syncjobs": "Sinhronizacijska opravila", - "pw_reset": "Dovoli ponastavitev uporabniškega gesla mailcow" + "pw_reset": "Dovoli ponastavitev uporabniškega gesla mailcow", + "alias_external_goto": "Dovoli vzdevke z zunanjimi domenami goto" }, "add": { "active": "Aktivno", @@ -559,7 +560,8 @@ "mx_invalid": "Zapis MX %s je neveljaven", "version_invalid": "Različica %s je neveljavna", "tfa_removal_blocked": "Dvofaktorske avtentikacije ni mogoče odstraniti, ker je obvezna za vaš račun.", - "quarantine_category_invalid": "Kategorija karantene mora biti ena od: add_header, reject, all" + "quarantine_category_invalid": "Kategorija karantene mora biti ena od: add_header, reject, all", + "external_goto_denied": "Zunanji naslov goto %s ni dovoljen" }, "debug": { "containers_info": "Informacije o zabojniku", diff --git a/data/web/lang/lang.zh-cn.json b/data/web/lang/lang.zh-cn.json index fe225a5df..2a1a080b9 100644 --- a/data/web/lang/lang.zh-cn.json +++ b/data/web/lang/lang.zh-cn.json @@ -29,7 +29,8 @@ "syncjobs": "同步任务", "tls_policy": "TLS 策略", "unlimited_quota": "无限邮箱容量配额", - "pw_reset": "允许重置mailcow使用者密码" + "pw_reset": "允许重置mailcow使用者密码", + "alias_external_goto": "允许带有外部目标地址的别名" }, "add": { "activate_filter_warn": "当“启用”选项被勾选后,其它所有的过滤器都会被禁用。", @@ -111,7 +112,8 @@ "validation_success": "验证成功", "dry": "模拟同步(Dry run)", "internal_info": "内部的别名只能在域内部或者别名域内部访问。", - "internal": "内部的" + "internal": "内部的", + "sender_allowed": "允许以该别名发送" }, "admin": { "access": "权限管理", @@ -555,7 +557,10 @@ "max_age_invalid": "最大有效时间 %s 无效", "mode_invalid": "模式 %s 无效", "mx_invalid": "MX 记录 %s 无效", - "version_invalid": "版本 %s 无效" + "version_invalid": "版本 %s 无效", + "tfa_removal_blocked": "无法移除两步验证,你的账户必须使用两步验证。", + "external_goto_denied": "不允许使用外部目标地址 %s", + "quarantine_category_invalid": "隔离分类必须是 add_header, reject, all 的其中一个" }, "debug": { "chart_this_server": "图表 (此服务器)", @@ -754,7 +759,10 @@ "mta_sts_max_age_info": "接收方邮件服务器可缓存该策略的时长(秒),超出后需重新获取策略。", "mta_sts_mx": "MX 服务器", "mta_sts_mx_info": "仅允许向明确列出的邮件服务器发送邮件;发送方 MTA 会验证 DNS MX 记录的主机名是否与策略列表匹配,并仅允许携带有效 TLS 证书的投递(可防范中间人攻击)。", - "mta_sts_mx_notice": "可配置多个 MX 服务器(以逗号分隔)。" + "mta_sts_mx_notice": "可配置多个 MX 服务器(以逗号分隔)。", + "sender_allowed": "允许以此别名发送", + "sender_allowed_info": "如果禁用了,此别名只能接收邮件。使用发件者 ACL 来覆盖此选项并赋予指定的邮箱发送权限。", + "mta_sts_active_info": "如果未选中,MTA-STS 策略不会被公布并且不会通过 ACME 为 MTA-STS 子域名请求证书。" }, "fido2": { "confirm": "确认", @@ -1002,7 +1010,8 @@ "templates": "模板", "template": "模板", "iam": "身份提供者(IDP)", - "internal": "内部的" + "internal": "内部的", + "force_tfa": "两步验证" }, "oauth2": { "access_denied": "请作为邮箱所有者登录以使用 OAuth2 授权。", @@ -1210,7 +1219,12 @@ "waiting_usb_auth": "等待 USB 设备中...

现在请触碰你的 WebAuthn USB 设备上的按钮。", "waiting_usb_register": "等待 USB 设备中...

请在上方输入你的密码并请触碰你的 WebAuthn USB 设备上的按钮以确认注册该 WebAuthn 设备。", "yubi_otp": "Yubico OTP 认证", - "authenticators": "验证器(Authenticators)" + "authenticators": "验证器(Authenticators)", + "force_tfa": "在登录时强制启用 2FA", + "force_tfa_info": "在访问面板前用户会被要求设置两步验证。", + "setup_title": "需要设置两步验证", + "setup_required": "你的账户需要设置两步验证。请添加一个两步验证方法以继续。", + "cancel_setup": "取消并注销" }, "user": { "action": "操作", @@ -1384,7 +1398,8 @@ "overview": "概览", "expire_never": "永不过期", "forever": "永久", - "spam_aliases_info": "垃圾邮件别名是一种临时电子邮件地址,可用于保护真实电子邮件地址。
还可以选择设置过期时间,以便在设定的时间后自动停用别名,从而有效地销毁被滥用或泄露的地址。" + "spam_aliases_info": "垃圾邮件别名是一种临时电子邮件地址,可用于保护真实电子邮件地址。
还可以选择设置过期时间,以便在设定的时间后自动停用别名,从而有效地销毁被滥用或泄露的地址。", + "pw_update_required": "你的账户需要修改一次密码。请设置一个新密码以继续。" }, "warning": { "cannot_delete_self": "不能删除已登录的用户", From fe4e675754398166db26ee878439128f4b76a965 Mon Sep 17 00:00:00 2001 From: milkmaker Date: Wed, 9 Sep 2026 22:28:28 +0200 Subject: [PATCH 14/17] [Web] Updated lang.it-it.json (#7460) Co-authored-by: Stefano --- data/web/lang/lang.it-it.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/data/web/lang/lang.it-it.json b/data/web/lang/lang.it-it.json index 267f3b447..de228b2d7 100644 --- a/data/web/lang/lang.it-it.json +++ b/data/web/lang/lang.it-it.json @@ -109,7 +109,10 @@ "bcc_dest_format": "Il destinatario in copia nascosta deve essere un singolo indirizzo email.
Se si vuole spedire una copia del messaggio a più destinatari, bisogna creare un alias ed utilizzarlo per questa opzione.", "app_passwd_protocols": "Protocolli consentiti per la password dell'app", "tags": "Tag", - "dry": "Simula sincronizzazione" + "dry": "Simula sincronizzazione", + "internal": "Interno", + "internal_info": "Gli alias interni sono accessibili solo dal proprio dominio o dai domini alias.", + "sender_allowed": "Consenti l'invio con questo alias" }, "admin": { "access": "Accedi", From 42d387ca42435285d735ccd3b3a42375fd312c59 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 15 Sep 2026 16:52:39 +0000 Subject: [PATCH 15/17] Update redis Docker tag to v7.4.11 Signed-off-by: milkmaker --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 32fa1cba8..7de6799b7 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -42,7 +42,7 @@ services: - mysql redis-mailcow: - image: redis:7.4.10-alpine + image: redis:7.4.11-alpine entrypoint: ["/bin/sh","/redis-conf.sh"] volumes: - redis-vol-1:/data/ From a480a96e10e35fa01e90fa79aa66412798c428fb Mon Sep 17 00:00:00 2001 From: FreddleSpl0it <75116288+FreddleSpl0it@users.noreply.github.com> Date: Mon, 21 Sep 2026 08:23:03 +0200 Subject: [PATCH 16/17] [Unbound] Update to 1.26.1 --- data/Dockerfiles/unbound/Dockerfile | 3 ++- docker-compose.yml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/data/Dockerfiles/unbound/Dockerfile b/data/Dockerfiles/unbound/Dockerfile index b1ec99e4f..321158e07 100644 --- a/data/Dockerfiles/unbound/Dockerfile +++ b/data/Dockerfiles/unbound/Dockerfile @@ -3,7 +3,8 @@ 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 +# minimum version is pinned +RUN apk add --no-cache --repository=https://dl-cdn.alpinelinux.org/alpine/edge/main "unbound>=1.26.1-r0" # install other packages from regular alpine stable repo RUN apk add --update --no-cache \ diff --git a/docker-compose.yml b/docker-compose.yml index 32fa1cba8..2945fed08 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.26.1-1 environment: - TZ=${TZ} - SKIP_UNBOUND_HEALTHCHECK=${SKIP_UNBOUND_HEALTHCHECK:-n} From a28fa1904471958fa818d16b97045e1932c29695 Mon Sep 17 00:00:00 2001 From: FreddleSpl0it <75116288+FreddleSpl0it@users.noreply.github.com> Date: Mon, 21 Sep 2026 08:43:16 +0200 Subject: [PATCH 17/17] [SOGo] Update to 5.12.11 --- data/Dockerfiles/sogo/Dockerfile | 6 +++--- docker-compose.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/data/Dockerfiles/sogo/Dockerfile b/data/Dockerfiles/sogo/Dockerfile index f65ec7ebd..2b22be27d 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.11 # # 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.10 -ARG SOPE_VERSION=SOPE-5.12.10 +ARG SOGO_VERSION=SOGo-5.12.11 +ARG SOPE_VERSION=SOPE-5.12.11 # 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/docker-compose.yml b/docker-compose.yml index 2945fed08..a72b80b8a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -200,7 +200,7 @@ services: - phpfpm sogo-mailcow: - image: ghcr.io/mailcow/sogo:5.12.10-1 + image: ghcr.io/mailcow/sogo:5.12.11-1 environment: - DBNAME=${DBNAME} - DBUSER=${DBUSER}