Compare commits

..
Author SHA1 Message Date
FreddleSpl0it 02552ffefd Merge pull request #7427 from mailcow/staging
Update 2026-07b
2026-08-18 09:29:10 +02:00
FreddleSpl0it 06424670fa Merge pull request #7393 from mailcow/staging
update README.md sponsors
2026-08-05 09:00:52 +02:00
FreddleSpl0it 489db90512 Merge pull request #7391 from mailcow/staging
Update 2026-07a
2026-07-30 11:17:15 +02:00
FreddleSpl0it 641ed63782 Merge pull request #7353 from mailcow/staging
update README.md sponsors
2026-07-15 08:31:16 +02:00
FreddleSpl0it 96a70652c3 Merge pull request #7328 from mailcow/staging
Update 2026-07
2026-07-13 10:42:55 +02:00
FreddleSpl0it 2ac4b1deae Merge pull request #7260 from mailcow/staging
Update 2026-05c
2026-05-26 10:50:58 +02:00
FreddleSpl0it 1eb6d2e26c Merge pull request #7243 from mailcow/staging
Update 2025-05b
2026-05-21 08:33:36 +02:00
FreddleSpl0it 384e2f6ac1 Merge pull request #7227 from mailcow/staging
Update 2026-05a
2026-05-13 10:42:14 +02:00
FreddleSpl0it 32156a337a Merge pull request #7221 from mailcow/staging
Update 2026-05
2026-05-12 08:46:25 +02:00
FreddleSpl0it 281cf93db3 Merge pull request #7174 from mailcow/staging
Update 2026-03b
2026-03-31 09:57:16 +02:00
FreddleSpl0it f399c07c85 Merge pull request #7137 from mailcow/staging
Hotfix 2026-03a
2026-03-13 14:15:04 +01:00
FreddleSpl0it a693325fe6 Merge pull request #7135 from mailcow/staging
Update 2026-03a
2026-03-13 13:16:32 +01:00
FreddleSpl0it 9ad84eee92 Merge pull request #7113 from mailcow/staging
Hotfix 2026-03
2026-03-10 13:50:33 +01:00
FreddleSpl0it b59869b720 Merge pull request #7109 from mailcow/staging
Hotfix 2026-03
2026-03-10 10:39:43 +01:00
FreddleSpl0it 7515bef66c Merge pull request #7104 from mailcow/staging
Hotfix 2026-03
2026-03-10 10:05:39 +01:00
FreddleSpl0it b84ba8ded1 Merge pull request #7101 from mailcow/staging
Update 2026-03
2026-03-10 08:08:29 +01:00
FreddleSpl0it 4845928e7a Merge pull request #7027 from mailcow/staging
[Hotfix] Update 2026-01
2026-01-29 10:31:23 +01:00
FreddleSpl0it 4ccfedd6b3 Merge pull request #7024 from mailcow/staging
🐄🛡️ January 2026 Update | Limited EAS/DAV Access and Restricted Alias Sending
2026-01-29 07:25:09 +01:00
Ashitaka e8d9315d4a Merge pull request #6905 from Ashitaka57/6646-pbkdf2-sha512-verify-hash
Support for PBKDF2-SHA512 hash algorithm in verify_hash() (FreeIPA compatibility) (issue 6646)
2025-12-12 14:08:21 +01:00
DerLinkman d977ddb501 backup: add image prefetch function to verify latest image is used 2025-12-12 14:07:57 +01:00
DerLinkman e76f5237ed ofelia: revert fixed cron syntax for sa-rules download 2025-12-12 14:07:47 +01:00
c11ed5dd1e Prevent duplicate/plaintext login announcement rendering (#6963)
* Initial plan

* Fix duplicate login announcement display

Co-authored-by: DerLinkman <62480600+DerLinkman@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: DerLinkman <62480600+DerLinkman@users.noreply.github.com>
2025-12-12 14:07:36 +01:00
DerLinkman 4ef65fc382 Merge pull request #6948 from mailcow/staging
2025-12
2025-12-09 13:29:15 +01:00
22 changed files with 54 additions and 133 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ ARG MEMCACHED_PECL_VERSION=3.4.0
# renovate: datasource=github-tags depName=phpredis/phpredis versioning=semver-coerced extractVersion=(?<version>.*)$
ARG REDIS_PECL_VERSION=6.3.0
# renovate: datasource=github-tags depName=composer/composer versioning=semver-coerced extractVersion=(?<version>.*)$
ARG COMPOSER_VERSION=2.10.3
ARG COMPOSER_VERSION=2.10.2
RUN apk add -U --no-cache autoconf \
aspell-dev \
+3 -3
View File
@@ -1,17 +1,17 @@
FROM golang:1.26-trixie AS builder
FROM golang:1.25-bookworm AS builder
WORKDIR /src
ENV CGO_ENABLED=0 \
GO111MODULE=on \
NOOPT=1 \
VERSION=1.11.0
VERSION=1.8.22
RUN git clone --branch v${VERSION} https://github.com/Zuplu/postfix-tlspol && \
cd /src/postfix-tlspol && \
scripts/build.sh build-only
FROM debian:trixie-slim
FROM debian:bookworm-slim
LABEL maintainer="The Infrastructure Company GmbH <info@servercow.de>"
ARG DEBIAN_FRONTEND=noninteractive
@@ -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 {
@@ -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 {
+1 -10
View File
@@ -32,17 +32,8 @@ 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 " .. tostring(c) .. " for user " .. request.user)
dovecot.i_info("HTTP request failed with " .. c .. " for user " .. request.user)
return dovecot.auth.PASSDB_RESULT_PASSWORD_MISMATCH, "Upstream error"
end
+1 -1
View File
@@ -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:QUERYwithTLSRPT
smtp_tls_policy_maps = proxy:mysql:/opt/postfix/conf/sql/mysql_tls_policy_override_maps.cf socketmap:inet:postfix-tlspol:8642:QUERY
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 "*"
+36 -23
View File
@@ -1,6 +1,6 @@
# Whitelist generated by Postwhite v3.4 on Tue Sep 1 00:34:07 UTC 2026
# Whitelist generated by Postwhite v3.4 on Sat Aug 1 00:35:20 UTC 2026
# https://github.com/stevejenkins/postwhite/
# 2243 total rules
# 2256 total rules
2a00:1450:4000::/36 permit
2a00:1450:4864::/56 permit
2a01:111:f400::/48 permit
@@ -125,6 +125,7 @@
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
@@ -146,7 +147,24 @@
27.123.206.80/28 permit
31.47.251.17 permit
31.186.239.0/24 permit
34.2.64.0/19 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.70.158.162 permit
34.74.74.140 permit
34.83.159.189 permit
@@ -173,7 +191,6 @@
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
@@ -247,8 +264,8 @@
46.228.39.112/31 permit
46.243.88.174 permit
46.243.88.175 permit
46.243.88.176/30 permit
46.243.95.96/27 permit
46.243.88.176 permit
46.243.88.177 permit
46.243.95.179 permit
46.243.95.180 permit
50.16.246.183 permit
@@ -266,7 +283,6 @@
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
@@ -638,7 +654,6 @@
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
@@ -723,7 +738,6 @@
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
@@ -1219,6 +1233,8 @@
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
@@ -1440,7 +1456,6 @@
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
@@ -1524,6 +1539,9 @@
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
@@ -1546,11 +1564,10 @@
149.97.173.180 permit
149.118.160.128/25 permit
150.136.21.199 permit
150.171.109.183 permit
150.171.109.72 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
@@ -1572,7 +1589,6 @@
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
@@ -1600,8 +1616,6 @@
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
@@ -1633,6 +1647,7 @@
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
@@ -1787,9 +1802,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
@@ -1814,6 +1829,7 @@
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
@@ -1856,6 +1872,7 @@
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
@@ -1942,7 +1959,6 @@
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
@@ -1950,9 +1966,7 @@
204.141.32.0/23 permit
204.141.42.0/23 permit
204.216.164.202 permit
204.220.90.0/23 permit
204.220.92.0/22 permit
204.220.160.0/20 permit
204.220.160.0/21 permit
204.220.168.0/21 permit
204.220.176.0/20 permit
204.220.181.105 permit
@@ -1988,8 +2002,6 @@
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
@@ -2039,6 +2051,7 @@
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
@@ -2225,7 +2238,7 @@
2001:748:400:3301::4 permit
2404:6800:4000::/36 permit
2404:6800:4864::/56 permit
2603:1061:14:102::1 permit
2603:1061:14:75::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
+1 -21
View File
@@ -442,16 +442,6 @@ 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))) {
@@ -472,26 +462,16 @@ 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 .= $val;
$dns_data .= str_replace($domain, $domain . '.', $val);
}
}
}
+1 -22
View File
@@ -633,18 +633,6 @@ 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)) {
@@ -3563,16 +3551,7 @@ function protect_route($allowed_roles = ['admin', 'domainadmin', 'user'], $redir
if (isset($redirects['unauthenticated'])) {
header('Location: ' . $redirects['unauthenticated']);
} else {
// 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: /');
}
header('Location: /');
}
exit();
}
-25
View File
@@ -750,18 +750,6 @@ 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");
@@ -2727,19 +2715,6 @@ 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',
+2 -3
View File
@@ -4,7 +4,7 @@ function init_db_schema()
try {
global $pdo;
$db_version = "18082026_1200";
$db_version = "19022026_1220";
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
@@ -719,8 +719,7 @@ 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'",
"alias_external_goto" => "TINYINT(1) NOT NULL DEFAULT '1'"
"domain_desc" => "TINYINT(1) NOT NULL DEFAULT '0'"
),
"keys" => array(
"primary" => array(
-4
View File
@@ -246,10 +246,6 @@ $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
-2
View File
@@ -1,7 +1,6 @@
{
"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)",
@@ -444,7 +443,6 @@
"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",
-2
View File
@@ -1,7 +1,6 @@
{
"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",
@@ -445,7 +444,6 @@
"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",
+1 -1
View File
@@ -131,7 +131,7 @@
"additional_rows": " righe aggiuntive inserite",
"admin": "Amministratore",
"admin_details": "Modifica impostazioni amministratore",
"admin_domains": "Assegnazioni di dominio",
"admin_domains": "Assengazioni di dominio",
"admins": "Amministratori",
"admins_ldap": "Amministratori LDAP",
"advanced_settings": "Impostazioni avanzate",
+1 -2
View File
@@ -785,8 +785,7 @@
"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.",
"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."
"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."
},
"footer": {
"restart_container_info": "<b>Pomembno:</b> Eleganten ponovni zagon lahko traja nekaj časa, zato počakajte, da se konča.",
-1
View File
@@ -49,7 +49,6 @@
<div class="input-group">
<div class="input-group-text"><i class="bi bi-lock-fill"></i></div>
<input name="pass_user" type="password" id="pass_user" class="form-control" placeholder="{{ lang.login.password }}" required="" autocomplete="current-password">
<button type="button" class="input-group-text" style="cursor:pointer;" onclick="var i=document.getElementById('pass_user'),ic=this.querySelector('i');if(i.type==='password'){i.type='text';ic.className='bi bi-eye-slash';}else{i.type='password';ic.className='bi bi-eye';}" tabindex="-1" aria-label="Toggle password visibility"><i class="bi bi-eye"></i></button>
</div>
</div>
<div class="d-flex justify-content-between mt-4" style="position: relative">
-4
View File
@@ -473,10 +473,6 @@ 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);
}
},
@@ -49,7 +49,6 @@
<div class="input-group">
<div class="input-group-text"><i class="bi bi-lock-fill"></i></div>
<input name="pass_user" type="password" id="pass_user" class="form-control" placeholder="{{ lang.login.password }}" required="" autocomplete="current-password">
<button type="button" class="input-group-text" style="cursor:pointer;" onclick="var i=document.getElementById('pass_user'),ic=this.querySelector('i');if(i.type==='password'){i.type='text';ic.className='bi bi-eye-slash';}else{i.type='password';ic.className='bi bi-eye';}" tabindex="-1" aria-label="Toggle password visibility"><i class="bi bi-eye"></i></button>
</div>
</div>
<div class="d-flex justify-content-between mt-4" style="position: relative">
+1 -1
View File
@@ -267,7 +267,6 @@
<small class="text-muted">{{ lang.admin.password_reset_info }}</small>
</div>
</div>
{% endif %}
<div data-acl="{{ acl.extend_sender_acl }}" class="row mb-4">
<label class="control-label col-sm-2" for="extended_sender_acl">{{ lang.edit.extended_sender_acl }}</label>
<div class="col-sm-10">
@@ -280,6 +279,7 @@
{% endif %}
</div>
</div>
{% endif %}
<div class="row">
<label class="control-label col-sm-2" for="protocol_access">{{ lang.edit.allowed_protocols }}</label>
<div class="col-sm-10">
-1
View File
@@ -56,7 +56,6 @@
<div class="input-group">
<div class="input-group-text"><i class="bi bi-lock-fill"></i></div>
<input name="pass_user" type="password" id="pass_user" class="form-control" placeholder="{{ lang.login.password }}" required="" autocomplete="current-password">
<button type="button" class="input-group-text" style="cursor:pointer;" onclick="var i=document.getElementById('pass_user'),ic=this.querySelector('i');if(i.type==='password'){i.type='text';ic.className='bi bi-eye-slash';}else{i.type='password';ic.className='bi bi-eye';}" tabindex="-1" aria-label="Toggle password visibility"><i class="bi bi-eye"></i></button>
</div>
</div>
<div class="mt-2 text-muted" style="font-size: 0.9rem;">
+1 -1
View File
@@ -382,7 +382,7 @@ services:
- postfix
postfix-tlspol-mailcow:
image: ghcr.io/mailcow/postfix-tlspol:1.11.0
image: ghcr.io/mailcow/postfix-tlspol:1.8.23
depends_on:
unbound-mailcow:
condition: service_healthy