mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2025-12-28 17:21:30 +00:00
Merge remote-tracking branch 'origin/staging' into nightly
This commit is contained in:
2
.github/workflows/pr_to_nightly.yml
vendored
2
.github/workflows/pr_to_nightly.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Run the Action
|
||||
uses: devops-infra/action-pull-request@v0.6.0
|
||||
uses: devops-infra/action-pull-request@v0.6.1
|
||||
with:
|
||||
github_token: ${{ secrets.PRTONIGHTLY_ACTION_PAT }}
|
||||
title: Automatic PR to nightly from ${{ github.event.repository.updated_at}}
|
||||
|
||||
@@ -124,7 +124,7 @@ prefetch_images() {
|
||||
}
|
||||
|
||||
docker_garbage() {
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )"
|
||||
IMGS_TO_DELETE=()
|
||||
|
||||
declare -A IMAGES_INFO
|
||||
@@ -185,6 +185,7 @@ detect_major_update() {
|
||||
MAJOR_VERSIONS=(
|
||||
"2025-02"
|
||||
"2025-03"
|
||||
"2025-08"
|
||||
)
|
||||
|
||||
current_version=""
|
||||
|
||||
@@ -41,7 +41,7 @@ docker_daemon_edit(){
|
||||
! _has_kv ipv6 true && MISSING+=("ipv6: true")
|
||||
! grep -Eq '"fixed-cidr-v6"\s*:\s*".+"' "$DOCKER_DAEMON_CONFIG" \
|
||||
&& MISSING+=('fixed-cidr-v6: "fd00:dead:beef:c0::/80"')
|
||||
if [[ -n "$DOCKER_MAJOR" && "$DOCKER_MAJOR" -ge 27 ]]; then
|
||||
if [[ -n "$DOCKER_MAJOR" && "$DOCKER_MAJOR" -le 27 ]]; then
|
||||
_has_kv ipv6 true && ! _has_kv ip6tables true && MISSING+=("ip6tables: true")
|
||||
! _has_kv experimental true && MISSING+=("experimental: true")
|
||||
fi
|
||||
@@ -105,7 +105,7 @@ EOF
|
||||
}
|
||||
EOF
|
||||
fi
|
||||
echo "${GREEN}Created $DOCKER_DAEMON_CONFIG with IPv6 settings.${NC}"
|
||||
echo -e "${GREEN}Created $DOCKER_DAEMON_CONFIG with IPv6 settings.${NC}"
|
||||
echo "Restarting Docker..."
|
||||
(command -v systemctl &>/dev/null && systemctl restart docker) || service docker restart
|
||||
echo "Docker restarted."
|
||||
|
||||
@@ -49,7 +49,6 @@ adapt_new_options() {
|
||||
"DOVECOT_MASTER_PASS"
|
||||
"MAILCOW_PASS_SCHEME"
|
||||
"ADDITIONAL_SERVER_NAMES"
|
||||
"ACME_CONTACT"
|
||||
"WATCHDOG_VERBOSE"
|
||||
"WEBAUTHN_ONLY_TRUSTED_VENDORS"
|
||||
"SPAMHAUS_DQS_KEY"
|
||||
@@ -95,7 +94,7 @@ adapt_new_options() {
|
||||
echo '# Max log lines per service to keep in Redis logs' >> mailcow.conf
|
||||
echo "LOG_LINES=9999" >> mailcow.conf
|
||||
;;
|
||||
|
||||
|
||||
IPV4_NETWORK)
|
||||
echo '# Internal IPv4 /24 subnet, format n.n.n. (expands to n.n.n.0/24)' >> mailcow.conf
|
||||
echo "IPV4_NETWORK=172.22.1" >> mailcow.conf
|
||||
@@ -238,14 +237,6 @@ adapt_new_options() {
|
||||
echo '# Comma separated list without spaces! Example: ADDITIONAL_SERVER_NAMES=a.b.c,d.e.f' >> mailcow.conf
|
||||
echo 'ADDITIONAL_SERVER_NAMES=' >> mailcow.conf
|
||||
;;
|
||||
ACME_CONTACT)
|
||||
echo '# Lets Encrypt registration contact information' >> mailcow.conf
|
||||
echo '# Optional: Leave empty for none' >> mailcow.conf
|
||||
echo '# This value is only used on first order!' >> mailcow.conf
|
||||
echo '# Setting it at a later point will require the following steps:' >> mailcow.conf
|
||||
echo '# https://docs.mailcow.email/troubleshooting/debug-reset_tls/' >> mailcow.conf
|
||||
echo 'ACME_CONTACT=' >> mailcow.conf
|
||||
;;
|
||||
WEBAUTHN_ONLY_TRUSTED_VENDORS)
|
||||
echo "# WebAuthn device manufacturer verification" >> mailcow.conf
|
||||
echo '# After setting WEBAUTHN_ONLY_TRUSTED_VENDORS=y only devices from trusted manufacturers are allowed' >> mailcow.conf
|
||||
@@ -285,7 +276,7 @@ adapt_new_options() {
|
||||
echo '# A COMPLETE DOCKER STACK REBUILD (compose down && compose up -d) IS NEEDED TO APPLY THIS.' >> mailcow.conf
|
||||
echo ENABLE_IPV6=${IPV6_BOOL} >> mailcow.conf
|
||||
;;
|
||||
|
||||
|
||||
SKIP_CLAMD)
|
||||
echo '# Skip ClamAV (clamd-mailcow) anti-virus (Rspamd will auto-detect a missing ClamAV container) - y/n' >> mailcow.conf
|
||||
echo 'SKIP_CLAMD=n' >> mailcow.conf
|
||||
@@ -295,11 +286,11 @@ adapt_new_options() {
|
||||
echo '# Skip Olefy (olefy-mailcow) anti-virus for Office documents (Rspamd will auto-detect a missing Olefy container) - y/n' >> mailcow.conf
|
||||
echo 'SKIP_OLEFY=n' >> mailcow.conf
|
||||
;;
|
||||
|
||||
|
||||
REDISPASS)
|
||||
echo "REDISPASS=$(LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 2>/dev/null | head -c 28)" >> mailcow.conf
|
||||
;;
|
||||
|
||||
|
||||
*)
|
||||
echo "${option}=" >> mailcow.conf
|
||||
;;
|
||||
|
||||
@@ -3,7 +3,7 @@ FROM alpine:3.21
|
||||
LABEL maintainer="The Infrastructure Company GmbH <info@servercow.de>"
|
||||
|
||||
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?<version>.*)$
|
||||
ARG GOSU_VERSION=1.16
|
||||
ARG GOSU_VERSION=1.17
|
||||
|
||||
ENV LANG=C.UTF-8
|
||||
ENV LC_ALL=C.UTF-8
|
||||
|
||||
@@ -76,7 +76,7 @@ try:
|
||||
|
||||
def notify_rcpt(rcpt, msg_count, quarantine_acl, category):
|
||||
if category == "add_header": category = "add header"
|
||||
meta_query = query_mysql('SELECT SHA2(CONCAT(id, qid), 256) AS qhash, id, subject, score, sender, created, action FROM quarantine WHERE notified = 0 AND rcpt = "%s" AND score < %f AND (action = "%s" OR "all" = "%s")' % (rcpt, max_score, category, category))
|
||||
meta_query = query_mysql('SELECT `qhash`, id, subject, score, sender, created, action FROM quarantine WHERE notified = 0 AND rcpt = "%s" AND score < %f AND (action = "%s" OR "all" = "%s")' % (rcpt, max_score, category, category))
|
||||
print("%s: %d of %d messages qualify for notification" % (rcpt, len(meta_query), msg_count))
|
||||
if len(meta_query) == 0:
|
||||
return
|
||||
|
||||
@@ -3,15 +3,15 @@ FROM php:8.2-fpm-alpine3.21
|
||||
LABEL maintainer = "The Infrastructure Company GmbH <info@servercow.de>"
|
||||
|
||||
# renovate: datasource=github-tags depName=krakjoe/apcu versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
||||
ARG APCU_PECL_VERSION=5.1.24
|
||||
ARG APCU_PECL_VERSION=5.1.26
|
||||
# renovate: datasource=github-tags depName=Imagick/imagick versioning=semver-coerced extractVersion=(?<version>.*)$
|
||||
ARG IMAGICK_PECL_VERSION=3.8.0
|
||||
# renovate: datasource=github-tags depName=php/pecl-mail-mailparse versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
||||
ARG MAILPARSE_PECL_VERSION=3.1.8
|
||||
# renovate: datasource=github-tags depName=php-memcached-dev/php-memcached versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
||||
ARG MEMCACHED_PECL_VERSION=3.2.0
|
||||
ARG MEMCACHED_PECL_VERSION=3.3.0
|
||||
# renovate: datasource=github-tags depName=phpredis/phpredis versioning=semver-coerced extractVersion=(?<version>.*)$
|
||||
ARG REDIS_PECL_VERSION=6.1.0
|
||||
ARG REDIS_PECL_VERSION=6.2.0
|
||||
# renovate: datasource=github-tags depName=composer/composer versioning=semver-coerced extractVersion=(?<version>.*)$
|
||||
ARG COMPOSER_VERSION=2.8.6
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ FROM debian:bookworm-slim
|
||||
LABEL maintainer="The Infrastructure Company GmbH <info@servercow.de>"
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG RSPAMD_VER=rspamd_3.11.1-1~ab0b44951
|
||||
ARG RSPAMD_VER=rspamd_3.12.1-1~6dbfca2fa
|
||||
ARG CODENAME=bookworm
|
||||
ENV LC_ALL=C
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ rspamd_config:register_symbol({
|
||||
local rcpt_split = rspamd_str_split(rcpt['addr'], '@')
|
||||
if #rcpt_split == 2 then
|
||||
if rcpt_split[1] == 'postmaster' then
|
||||
task:set_pre_result('accept', 'whitelisting postmaster smtp rcpt')
|
||||
task:set_pre_result('accept', 'whitelisting postmaster smtp rcpt', 'postmaster')
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -167,7 +167,7 @@ rspamd_config:register_symbol({
|
||||
for k,v in pairs(data) do
|
||||
if (v and v ~= userdata and v == '1') then
|
||||
rspamd_logger.infox(rspamd_config, "found ip in keep_spam map, setting pre-result")
|
||||
task:set_pre_result('accept', 'ip matched with forward hosts')
|
||||
task:set_pre_result('accept', 'ip matched with forward hosts', 'keep_spam')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -236,6 +236,9 @@ foreach ($rcpt_final_mailboxes as $rcpt_final) {
|
||||
':action' => $action,
|
||||
':fuzzy_hashes' => $fuzzy
|
||||
));
|
||||
$lastId = $pdo->lastInsertId();
|
||||
$stmt_update = $pdo->prepare("UPDATE `quarantine` SET `qhash` = SHA2(CONCAT(`id`, `qid`), 256) WHERE `id` = :id");
|
||||
$stmt_update->execute(array(':id' => $lastId));
|
||||
$stmt = $pdo->prepare('DELETE FROM `quarantine` WHERE `rcpt` = :rcpt AND `id` NOT IN (
|
||||
SELECT `id`
|
||||
FROM (
|
||||
|
||||
@@ -125,6 +125,7 @@ if (isset($_SESSION['mailcow_cc_role'])) {
|
||||
'mailbox' => $mailbox,
|
||||
'rl' => $rl,
|
||||
'pushover_data' => $pushover_data,
|
||||
'get_tagging_options' => mailbox('get', 'delimiter_action', $mailbox),
|
||||
'quarantine_notification' => $quarantine_notification,
|
||||
'quarantine_category' => $quarantine_category,
|
||||
'get_tls_policy' => $get_tls_policy,
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 17 KiB |
@@ -1223,6 +1223,14 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$stmt->execute(array(
|
||||
':username' => $username
|
||||
));
|
||||
// save delimiter_action
|
||||
if (isset($_data['tagged_mail_handler'])) {
|
||||
mailbox('edit', 'delimiter_action', array(
|
||||
'username' => $username,
|
||||
'tagged_mail_handler' => $_data['tagged_mail_handler']
|
||||
));
|
||||
}
|
||||
|
||||
// save tags
|
||||
foreach($tags as $index => $tag){
|
||||
if (empty($tag)) continue;
|
||||
@@ -1613,6 +1621,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$attr = array();
|
||||
$attr["quota"] = isset($_data['quota']) ? intval($_data['quota']) * 1048576 : 0;
|
||||
$attr['tags'] = (isset($_data['tags'])) ? $_data['tags'] : array();
|
||||
$attr["tagged_mail_handler"] = (!empty($_data['tagged_mail_handler'])) ? $_data['tagged_mail_handler'] : strval($MAILBOX_DEFAULT_ATTRIBUTES['tagged_mail_handler']);
|
||||
$attr["quarantine_notification"] = (!empty($_data['quarantine_notification'])) ? $_data['quarantine_notification'] : strval($MAILBOX_DEFAULT_ATTRIBUTES['quarantine_notification']);
|
||||
$attr["quarantine_category"] = (!empty($_data['quarantine_category'])) ? $_data['quarantine_category'] : strval($MAILBOX_DEFAULT_ATTRIBUTES['quarantine_category']);
|
||||
$attr["rl_frame"] = (!empty($_data['rl_frame'])) ? $_data['rl_frame'] : "s";
|
||||
@@ -3259,6 +3268,13 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
);
|
||||
return false;
|
||||
}
|
||||
// save delimiter_action
|
||||
if (isset($_data['tagged_mail_handler'])) {
|
||||
mailbox('edit', 'delimiter_action', array(
|
||||
'username' => $username,
|
||||
'tagged_mail_handler' => $_data['tagged_mail_handler']
|
||||
));
|
||||
}
|
||||
// save tags
|
||||
foreach($tags as $index => $tag){
|
||||
if (empty($tag)) continue;
|
||||
@@ -3604,6 +3620,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$attr = array();
|
||||
$attr["quota"] = isset($_data['quota']) ? intval($_data['quota']) * 1048576 : 0;
|
||||
$attr['tags'] = (isset($_data['tags'])) ? $_data['tags'] : $is_now['tags'];
|
||||
$attr["tagged_mail_handler"] = (!empty($_data['tagged_mail_handler'])) ? $_data['tagged_mail_handler'] : $is_now['tagged_mail_handler'];
|
||||
$attr["quarantine_notification"] = (!empty($_data['quarantine_notification'])) ? $_data['quarantine_notification'] : $is_now['quarantine_notification'];
|
||||
$attr["quarantine_category"] = (!empty($_data['quarantine_category'])) ? $_data['quarantine_category'] : $is_now['quarantine_category'];
|
||||
$attr["rl_frame"] = (!empty($_data['rl_frame'])) ? $_data['rl_frame'] : $is_now['rl_frame'];
|
||||
|
||||
@@ -22,7 +22,7 @@ function quarantine($_action, $_data = null) {
|
||||
return false;
|
||||
}
|
||||
$stmt = $pdo->prepare('SELECT `id` FROM `quarantine` LEFT OUTER JOIN `user_acl` ON `user_acl`.`username` = `rcpt`
|
||||
WHERE SHA2(CONCAT(`id`, `qid`), 256) = :hash
|
||||
WHERE `qhash` = :hash
|
||||
AND user_acl.quarantine = 1
|
||||
AND rcpt IN (SELECT username FROM mailbox)');
|
||||
$stmt->execute(array(':hash' => $hash));
|
||||
@@ -65,7 +65,7 @@ function quarantine($_action, $_data = null) {
|
||||
return false;
|
||||
}
|
||||
$stmt = $pdo->prepare('SELECT `id` FROM `quarantine` LEFT OUTER JOIN `user_acl` ON `user_acl`.`username` = `rcpt`
|
||||
WHERE SHA2(CONCAT(`id`, `qid`), 256) = :hash
|
||||
WHERE `qhash` = :hash
|
||||
AND `user_acl`.`quarantine` = 1
|
||||
AND `username` IN (SELECT `username` FROM `mailbox`)');
|
||||
$stmt->execute(array(':hash' => $hash));
|
||||
@@ -833,7 +833,7 @@ function quarantine($_action, $_data = null) {
|
||||
)));
|
||||
return false;
|
||||
}
|
||||
$stmt = $pdo->prepare('SELECT * FROM `quarantine` WHERE SHA2(CONCAT(`id`, `qid`), 256) = :hash');
|
||||
$stmt = $pdo->prepare('SELECT * FROM `quarantine` WHERE `qhash` = :hash');
|
||||
$stmt->execute(array(':hash' => $hash));
|
||||
return $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
break;
|
||||
|
||||
@@ -4,7 +4,7 @@ function init_db_schema()
|
||||
try {
|
||||
global $pdo;
|
||||
|
||||
$db_version = "27012025_1555";
|
||||
$db_version = "06082025_1611";
|
||||
|
||||
$stmt = $pdo->query("SHOW TABLES LIKE 'versions'");
|
||||
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
|
||||
@@ -345,10 +345,14 @@ function init_db_schema()
|
||||
"notified" => "TINYINT(1) NOT NULL DEFAULT '0'",
|
||||
"created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)",
|
||||
"user" => "VARCHAR(255) NOT NULL DEFAULT 'unknown'",
|
||||
"qhash" => "VARCHAR(64)",
|
||||
),
|
||||
"keys" => array(
|
||||
"primary" => array(
|
||||
"" => array("id")
|
||||
),
|
||||
"key" => array(
|
||||
"qhash" => array("qhash")
|
||||
)
|
||||
),
|
||||
"attr" => "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC"
|
||||
@@ -1482,6 +1486,10 @@ function init_db_schema()
|
||||
'msg' => 'db_init_complete'
|
||||
);
|
||||
}
|
||||
|
||||
// fill quarantine.qhash
|
||||
$pdo->query("UPDATE `quarantine` SET `qhash` = SHA2(CONCAT(`id`, `qid`), 256) WHERE ISNULL(`qhash`)");
|
||||
|
||||
} catch (PDOException $e) {
|
||||
if (php_sapi_name() == "cli") {
|
||||
echo "DB initialization failed: " . print_r($e, true) . PHP_EOL;
|
||||
|
||||
@@ -186,6 +186,12 @@ $MAILBOX_DEFAULT_ATTRIBUTES['force_pw_update'] = false;
|
||||
// Enable SOGo access - Users will be redirected to SOGo after login (set to false to disable redirect by default)
|
||||
$MAILBOX_DEFAULT_ATTRIBUTES['sogo_access'] = true;
|
||||
|
||||
// How to handle tagged emails
|
||||
// none - No special handling
|
||||
// subfolder - Create subfolder under INBOX (e.g. "INBOX/Facebook")
|
||||
// subject - Add tag to subject (e.g. "[Facebook] Subject")
|
||||
$MAILBOX_DEFAULT_ATTRIBUTES['tagged_mail_handler'] = "none";
|
||||
|
||||
// Send notification when quarantine is not empty (never, hourly, daily, weekly)
|
||||
$MAILBOX_DEFAULT_ATTRIBUTES['quarantine_notification'] = 'hourly';
|
||||
|
||||
@@ -257,57 +263,57 @@ $RSPAMD_MAPS = array(
|
||||
|
||||
$IMAPSYNC_OPTIONS = array(
|
||||
'whitelist' => array(
|
||||
'abort',
|
||||
'authmd51',
|
||||
'authmd52',
|
||||
'abort',
|
||||
'authmd51',
|
||||
'authmd52',
|
||||
'authmech1',
|
||||
'authmech2',
|
||||
'authuser1',
|
||||
'authuser2',
|
||||
'debug',
|
||||
'debugcontent',
|
||||
'debugcrossduplicates',
|
||||
'debugflags',
|
||||
'debugfolders',
|
||||
'debugimap',
|
||||
'debugimap1',
|
||||
'debugimap2',
|
||||
'debugmemory',
|
||||
'debugssl',
|
||||
'authuser1',
|
||||
'authuser2',
|
||||
'debug',
|
||||
'debugcontent',
|
||||
'debugcrossduplicates',
|
||||
'debugflags',
|
||||
'debugfolders',
|
||||
'debugimap',
|
||||
'debugimap1',
|
||||
'debugimap2',
|
||||
'debugmemory',
|
||||
'debugssl',
|
||||
'delete1emptyfolders',
|
||||
'delete2folders',
|
||||
'disarmreadreceipts',
|
||||
'delete2folders',
|
||||
'disarmreadreceipts',
|
||||
'domain1',
|
||||
'domain2',
|
||||
'domino1',
|
||||
'domino2',
|
||||
'domino1',
|
||||
'domino2',
|
||||
'dry',
|
||||
'errorsmax',
|
||||
'exchange1',
|
||||
'exchange2',
|
||||
'exchange1',
|
||||
'exchange2',
|
||||
'exitwhenover',
|
||||
'expunge1',
|
||||
'f1f2',
|
||||
'filterbuggyflags',
|
||||
'f1f2',
|
||||
'filterbuggyflags',
|
||||
'folder',
|
||||
'folderfirst',
|
||||
'folderlast',
|
||||
'folderrec',
|
||||
'gmail1',
|
||||
'gmail2',
|
||||
'idatefromheader',
|
||||
'gmail1',
|
||||
'gmail2',
|
||||
'idatefromheader',
|
||||
'include',
|
||||
'inet4',
|
||||
'inet6',
|
||||
'justconnect',
|
||||
'justfolders',
|
||||
'justfoldersizes',
|
||||
'justlogin',
|
||||
'keepalive1',
|
||||
'keepalive2',
|
||||
'justconnect',
|
||||
'justfolders',
|
||||
'justfoldersizes',
|
||||
'justlogin',
|
||||
'keepalive1',
|
||||
'keepalive2',
|
||||
'log',
|
||||
'logdir',
|
||||
'logfile',
|
||||
'logfile',
|
||||
'maxbytesafter',
|
||||
'maxlinelength',
|
||||
'maxmessagespersecond',
|
||||
@@ -315,62 +321,62 @@ $IMAPSYNC_OPTIONS = array(
|
||||
'maxsleep',
|
||||
'minage',
|
||||
'minsize',
|
||||
'noabletosearch',
|
||||
'noabletosearch1',
|
||||
'noabletosearch2',
|
||||
'noexpunge1',
|
||||
'noexpunge2',
|
||||
'noabletosearch',
|
||||
'noabletosearch1',
|
||||
'noabletosearch2',
|
||||
'noexpunge1',
|
||||
'noexpunge2',
|
||||
'nofoldersizesatend',
|
||||
'noid',
|
||||
'nolog',
|
||||
'nomixfolders',
|
||||
'noresyncflags',
|
||||
'nossl1',
|
||||
'nossl2',
|
||||
'nosyncacls',
|
||||
'notls1',
|
||||
'notls2',
|
||||
'nouidexpunge2',
|
||||
'nousecache',
|
||||
'noid',
|
||||
'nolog',
|
||||
'nomixfolders',
|
||||
'noresyncflags',
|
||||
'nossl1',
|
||||
'nossl2',
|
||||
'nosyncacls',
|
||||
'notls1',
|
||||
'notls2',
|
||||
'nouidexpunge2',
|
||||
'nousecache',
|
||||
'oauthaccesstoken1',
|
||||
'oauthaccesstoken2',
|
||||
'oauthdirect1',
|
||||
'oauthdirect2',
|
||||
'office1',
|
||||
'office2',
|
||||
'pidfile',
|
||||
'pidfilelocking',
|
||||
'office1',
|
||||
'office2',
|
||||
'pidfile',
|
||||
'pidfilelocking',
|
||||
'prefix1',
|
||||
'prefix2',
|
||||
'proxyauth1',
|
||||
'proxyauth2',
|
||||
'resyncflags',
|
||||
'resynclabels',
|
||||
'search',
|
||||
'proxyauth1',
|
||||
'proxyauth2',
|
||||
'resyncflags',
|
||||
'resynclabels',
|
||||
'search',
|
||||
'search1',
|
||||
'search2',
|
||||
'search2',
|
||||
'sep1',
|
||||
'sep2',
|
||||
'showpasswords',
|
||||
'skipemptyfolders',
|
||||
'ssl2',
|
||||
'ssl2',
|
||||
'sslargs1',
|
||||
'sslargs2',
|
||||
'sslargs2',
|
||||
'subfolder1',
|
||||
'subscribe',
|
||||
'subscribe',
|
||||
'subscribed',
|
||||
'syncacls',
|
||||
'syncduplicates',
|
||||
'syncinternaldates',
|
||||
'synclabels',
|
||||
'tests',
|
||||
'testslive',
|
||||
'testslive6',
|
||||
'tls2',
|
||||
'truncmess',
|
||||
'usecache',
|
||||
'useheader',
|
||||
'useuid'
|
||||
'synclabels',
|
||||
'tests',
|
||||
'testslive',
|
||||
'testslive6',
|
||||
'tls2',
|
||||
'truncmess',
|
||||
'usecache',
|
||||
'useheader',
|
||||
'useuid'
|
||||
),
|
||||
'blacklist' => array(
|
||||
'skipmess',
|
||||
|
||||
@@ -269,6 +269,24 @@ $(document).ready(function() {
|
||||
function setMailboxTemplateData(template){
|
||||
$("#addInputQuota").val(template.quota / 1048576);
|
||||
|
||||
if (template.tagged_mail_handler === "subfolder"){
|
||||
$('#tagged_mail_handler_subfolder').prop('checked', true);
|
||||
$('#tagged_mail_handler_subject').prop('checked', false);
|
||||
$('#tagged_mail_handler_none').prop('checked', false);
|
||||
} else if(template.tagged_mail_handler === "subject"){
|
||||
$('#tagged_mail_handler_subfolder').prop('checked', false);
|
||||
$('#tagged_mail_handler_subject').prop('checked', true);
|
||||
$('#tagged_mail_handler_none').prop('checked', false);
|
||||
} else if(template.tagged_mail_handler === "none"){
|
||||
$('#tagged_mail_handler_subfolder').prop('checked', false);
|
||||
$('#tagged_mail_handler_subject').prop('checked', false);
|
||||
$('#tagged_mail_handler_none').prop('checked', true);
|
||||
} else {
|
||||
$('#tagged_mail_handler_subfolder').prop('checked', false);
|
||||
$('#tagged_mail_handler_subject').prop('checked', false);
|
||||
$('#tagged_mail_handler_none').prop('checked', true);
|
||||
}
|
||||
|
||||
if (template.quarantine_notification === "never"){
|
||||
$('#quarantine_notification_never').prop('checked', true);
|
||||
$('#quarantine_notification_hourly').prop('checked', false);
|
||||
|
||||
@@ -36,6 +36,23 @@
|
||||
<small class="text-muted">0 = ∞</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2">{{ lang.user.tag_handling }}</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="btn-group">
|
||||
<input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_subfolder" autocomplete="off" value="subfolder" {% if template.attributes.tagged_mail_handler == 'subfolder' %}checked{% endif %}>
|
||||
<label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_subfolder">{{ lang.user.tag_in_subfolder }}</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_subject" autocomplete="off" value="subject" {% if template.attributes.tagged_mail_handler == 'subject' %}checked{% endif %}>
|
||||
<label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_subject">{{ lang.user.tag_in_subject }}</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_none" autocomplete="off" value="none" {% if template.attributes.tagged_mail_handler == 'none' %}checked{% endif %}>
|
||||
<label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_none">{{ lang.user.tag_in_none }}</label>
|
||||
</div>
|
||||
<p class="text-muted"><small>{{ lang.user.tag_help_explain|raw }}</small></p>
|
||||
<p class="text-muted"><small>{{ lang.user.tag_help_example|raw }}</small></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2">{{ lang.user.quarantine_notification }}</label>
|
||||
<div class="col-sm-10">
|
||||
|
||||
@@ -117,7 +117,7 @@
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2" for="relayhost">{{ lang.edit.relayhost }}</label>
|
||||
<div class="col-sm-10">
|
||||
<select data-acl="{{ acl.mailbox_relayhost }}" data-live-search="true" id="relayhost" name="relayhost" class="form-control mb-4">
|
||||
<select data-acl="{{ acl.mailbox_relayhost }}" data-live-search="true" id="relayhost" name="relayhost" class="form-control">
|
||||
{% for rlyhost in rlyhosts %}
|
||||
<option
|
||||
style="{% if rlyhost.active != '1' %}background: #ff4136; color: #fff{% endif %}"
|
||||
@@ -131,7 +131,34 @@
|
||||
</option>
|
||||
</select>
|
||||
<p class="d-block d-sm-none" style="margin: 0;padding: 0"> </p>
|
||||
<small class="text-muted d-block">{{ lang.edit.mailbox_relayhost_info }}</small>
|
||||
<small class="text-muted d-block mb-4">{{ lang.edit.mailbox_relayhost_info }}</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2">{{ lang.user.tag_handling }}</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="btn-group" data-acl="{{ acl.delimiter_action }}">
|
||||
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline{% if get_tagging_options == 'subfolder' %} btn-dark{% else %} btn-light{% endif %}"
|
||||
data-action="edit_selected"
|
||||
data-item="{{ mailbox }}"
|
||||
data-id="delimiter_action"
|
||||
data-api-url='edit/delimiter_action'
|
||||
data-api-attr='{"tagged_mail_handler":"subfolder"}'>{{ lang.user.tag_in_subfolder }}</button>
|
||||
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline{% if get_tagging_options == 'subject' %} btn-dark{% else %} btn-light{% endif %}"
|
||||
data-action="edit_selected"
|
||||
data-item="{{ mailbox }}"
|
||||
data-id="delimiter_action"
|
||||
data-api-url='edit/delimiter_action'
|
||||
data-api-attr='{"tagged_mail_handler":"subject"}'>{{ lang.user.tag_in_subject }}</button>
|
||||
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline{% if get_tagging_options == 'none' %} btn-dark{% else %} btn-light{% endif %}"
|
||||
data-action="edit_selected"
|
||||
data-item="{{ mailbox }}"
|
||||
data-id="delimiter_action"
|
||||
data-api-url='edit/delimiter_action'
|
||||
data-api-attr='{"tagged_mail_handler":"none"}'>{{ lang.user.tag_in_none }}</button>
|
||||
</div>
|
||||
<p class="text-muted"><small>{{ lang.user.tag_help_explain|raw }}</small></p>
|
||||
<p class="text-muted"><small>{{ lang.user.tag_help_example|raw }}</small></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
|
||||
@@ -76,6 +76,23 @@
|
||||
<div class="badge fs-5 bg-warning addInputQuotaExhausted" style="display:none;">{{ lang.warning.quota_exceeded_scope }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2 text-sm-end text-sm-end">{{ lang.user.tag_handling }}</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="btn-group">
|
||||
<input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_subfolder" autocomplete="off" value="subfolder">
|
||||
<label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_subfolder">{{ lang.user.tag_in_subfolder }}</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_subject" autocomplete="off" value="subject">
|
||||
<label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_subject">{{ lang.user.tag_in_subject }}</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="tagged_mail_handler" id="tagged_mail_handler_none" autocomplete="off" value="none">
|
||||
<label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="tagged_mail_handler_none">{{ lang.user.tag_in_none }}</label>
|
||||
</div>
|
||||
<p class="text-muted"><small>{{ lang.user.tag_help_explain|raw }}</small></p>
|
||||
<p class="text-muted"><small>{{ lang.user.tag_help_example|raw }}</small></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2 text-sm-end text-sm-end">{{ lang.user.quarantine_notification }}</label>
|
||||
<div class="col-sm-10">
|
||||
@@ -246,6 +263,23 @@
|
||||
<small class="text-muted">0 = ∞</small>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2 text-sm-end text-sm-end">{{ lang.user.tag_handling }}</label>
|
||||
<div class="col-sm-10">
|
||||
<div class="btn-group">
|
||||
<input type="radio" class="btn-check" name="tagged_mail_handler" id="template_tagged_mail_handler_subfolder" autocomplete="off" value="subfolder">
|
||||
<label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="template_tagged_mail_handler_subfolder">{{ lang.user.tag_in_subfolder }}</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="tagged_mail_handler" id="template_tagged_mail_handler_subject" autocomplete="off" value="subject">
|
||||
<label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="template_tagged_mail_handler_subject">{{ lang.user.tag_in_subject }}</label>
|
||||
|
||||
<input type="radio" class="btn-check" name="tagged_mail_handler" id="template_tagged_mail_handler_none" autocomplete="off" value="none">
|
||||
<label class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light" for="template_tagged_mail_handler_none">{{ lang.user.tag_in_none }}</label>
|
||||
</div>
|
||||
<p class="text-muted"><small>{{ lang.user.tag_help_explain|raw }}</small></p>
|
||||
<p class="text-muted"><small>{{ lang.user.tag_help_example|raw }}</small></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb-2">
|
||||
<label class="control-label col-sm-2 text-sm-end text-sm-end">{{ lang.user.quarantine_notification }}</label>
|
||||
<div class="col-sm-10">
|
||||
|
||||
@@ -84,7 +84,7 @@ services:
|
||||
- clamd
|
||||
|
||||
rspamd-mailcow:
|
||||
image: ghcr.io/mailcow/rspamd:2.2
|
||||
image: ghcr.io/mailcow/rspamd:2.3
|
||||
stop_grace_period: 30s
|
||||
depends_on:
|
||||
- dovecot-mailcow
|
||||
|
||||
@@ -383,7 +383,6 @@ configure_ipv6
|
||||
[[ -f data/conf/nginx/ZZZ-ejabberd.conf ]] && rm data/conf/nginx/ZZZ-ejabberd.conf
|
||||
migrate_config_options
|
||||
adapt_new_options
|
||||
remove_obsolete_options
|
||||
|
||||
if [ ! "$DEV" ]; then
|
||||
DEFAULT_REPO="https://github.com/mailcow/mailcow-dockerized"
|
||||
@@ -434,7 +433,7 @@ if [ ! "$DEV" ]; then
|
||||
echo "Run $COMPOSE_COMMAND up -d to restart your stack without updates or try again after fixing the mentioned errors."
|
||||
exit 1
|
||||
fi
|
||||
elif [ "$DEV" ]; then
|
||||
else
|
||||
echo -e "\e[33mDEVELOPER MODE: Not creating a git diff and commiting it to prevent development stuff within a backup diff...\e[0m"
|
||||
fi
|
||||
|
||||
|
||||
Reference in New Issue
Block a user