mirror of
https://github.com/mailcow/mailcow-dockerized.git
synced 2026-06-15 19:10:31 +00:00
Compare commits
24 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e6c36dce1 | |||
| fa154c71f3 | |||
| 83a045ed3e | |||
| 064817ac70 | |||
| 2bd7a24b8c | |||
| ecc2462e4c | |||
| 2d8db72d46 | |||
| 277a307fb9 | |||
| d455555621 | |||
| 9ea2ff1dff | |||
| 24cc369d84 | |||
| 5f5367f2f9 | |||
| 03c31f825a | |||
| c0050e8836 | |||
| 15891960f7 | |||
| cce02e2b15 | |||
| 0fafda696b | |||
| 843db5854c | |||
| 23e4e4f373 | |||
| ffbc37a00c | |||
| 104af58628 | |||
| b0873edb6a | |||
| 694d751915 | |||
| 08278a8be9 |
@@ -12,7 +12,7 @@ jobs:
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Run the Action
|
||||
uses: devops-infra/action-pull-request@v1.2.1
|
||||
uses: devops-infra/action-pull-request@v1.3.0
|
||||
with:
|
||||
github_token: ${{ secrets.PRTONIGHTLY_ACTION_PAT }}
|
||||
title: Automatic PR to nightly from ${{ github.event.repository.updated_at}}
|
||||
|
||||
@@ -7,13 +7,13 @@ ARG APCU_PECL_VERSION=5.1.28
|
||||
# renovate: datasource=github-tags depName=Imagick/imagick versioning=semver-coerced extractVersion=(?<version>.*)$
|
||||
ARG IMAGICK_PECL_VERSION=3.8.1
|
||||
# renovate: datasource=github-tags depName=php/pecl-mail-mailparse versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
||||
ARG MAILPARSE_PECL_VERSION=3.1.9
|
||||
ARG MAILPARSE_PECL_VERSION=3.2.0
|
||||
# renovate: datasource=github-tags depName=php-memcached-dev/php-memcached versioning=semver-coerced extractVersion=^v(?<version>.*)$
|
||||
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.9.5
|
||||
ARG COMPOSER_VERSION=2.10.1
|
||||
|
||||
RUN apk add -U --no-cache autoconf \
|
||||
aspell-dev \
|
||||
|
||||
@@ -2,7 +2,7 @@ FROM debian:trixie-slim
|
||||
LABEL maintainer="The Infrastructure Company GmbH <info@servercow.de>"
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG RSPAMD_VER=rspamd_3.14.3-1~236eb65
|
||||
ARG RSPAMD_VER=rspamd_4.1.0-1~e2b0b18
|
||||
ARG CODENAME=trixie
|
||||
ENV LC_ALL=C
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# SOGo built from source to enable security patch application
|
||||
# Repository: https://github.com/Alinto/sogo
|
||||
# Version: SOGo-5.12.8
|
||||
# Version: SOGo-5.12.9
|
||||
#
|
||||
# Applied security patches:
|
||||
# -
|
||||
@@ -12,8 +12,8 @@ FROM debian:bookworm
|
||||
LABEL maintainer="The Infrastructure Company GmbH <info@servercow.de>"
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG SOGO_VERSION=SOGo-5.12.8
|
||||
ARG SOPE_VERSION=SOPE-5.12.8
|
||||
ARG SOGO_VERSION=SOGo-5.12.9
|
||||
ARG SOPE_VERSION=SOPE-5.12.9
|
||||
# Security patches to apply (space-separated commit hashes)
|
||||
ARG SOGO_SECURITY_PATCHES=""
|
||||
# renovate: datasource=github-releases depName=tianon/gosu versioning=semver-coerced extractVersion=^(?<version>.*)$
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Whitelist generated by Postwhite v3.4 on Fri May 1 00:43:37 UTC 2026
|
||||
# Whitelist generated by Postwhite v3.4 on Mon Jun 1 00:52:17 UTC 2026
|
||||
# https://github.com/stevejenkins/postwhite/
|
||||
# 2249 total rules
|
||||
# 2186 total rules
|
||||
2a00:1450:4000::/36 permit
|
||||
2a00:1450:4864::/56 permit
|
||||
2a01:111:f400::/48 permit
|
||||
@@ -56,14 +56,8 @@
|
||||
8.25.194.0/23 permit
|
||||
8.25.196.0/23 permit
|
||||
8.36.116.0/24 permit
|
||||
8.39.54.0/23 permit
|
||||
8.39.54.250/31 permit
|
||||
8.39.144.0/24 permit
|
||||
8.40.222.0/23 permit
|
||||
8.40.222.250/31 permit
|
||||
12.130.86.238 permit
|
||||
13.107.213.40 permit
|
||||
13.107.246.40 permit
|
||||
13.108.16.0/20 permit
|
||||
13.110.208.0/21 permit
|
||||
13.110.209.0/24 permit
|
||||
@@ -73,7 +67,6 @@
|
||||
13.111.191.0/24 permit
|
||||
13.216.7.111 permit
|
||||
13.216.54.180 permit
|
||||
13.247.164.219 permit
|
||||
15.200.21.50 permit
|
||||
15.200.44.248 permit
|
||||
15.200.201.185 permit
|
||||
@@ -177,7 +170,6 @@
|
||||
34.215.104.144 permit
|
||||
34.218.115.239 permit
|
||||
34.225.212.172 permit
|
||||
34.241.242.183 permit
|
||||
35.83.148.184 permit
|
||||
35.155.198.111 permit
|
||||
35.158.23.94 permit
|
||||
@@ -201,7 +193,6 @@
|
||||
40.233.64.216 permit
|
||||
40.233.83.78 permit
|
||||
40.233.88.28 permit
|
||||
43.239.212.33 permit
|
||||
44.206.138.57 permit
|
||||
44.210.169.44 permit
|
||||
44.217.45.156 permit
|
||||
@@ -284,7 +275,6 @@
|
||||
51.83.17.38 permit
|
||||
52.1.14.157 permit
|
||||
52.5.230.59 permit
|
||||
52.6.74.205 permit
|
||||
52.12.53.23 permit
|
||||
52.13.214.179 permit
|
||||
52.26.1.71 permit
|
||||
@@ -341,7 +331,6 @@
|
||||
54.244.54.130 permit
|
||||
54.244.242.0/24 permit
|
||||
54.255.61.23 permit
|
||||
56.124.6.228 permit
|
||||
57.103.64.0/18 permit
|
||||
57.129.93.249 permit
|
||||
62.13.128.0/24 permit
|
||||
@@ -408,7 +397,6 @@
|
||||
65.110.161.77 permit
|
||||
65.123.29.213 permit
|
||||
65.123.29.220 permit
|
||||
65.154.166.0/24 permit
|
||||
65.212.180.36 permit
|
||||
66.102.0.0/20 permit
|
||||
66.119.150.192/26 permit
|
||||
@@ -1222,9 +1210,6 @@
|
||||
99.78.197.208/28 permit
|
||||
103.9.96.0/22 permit
|
||||
103.28.42.0/24 permit
|
||||
103.84.217.15 permit
|
||||
103.84.217.238 permit
|
||||
103.89.75.238 permit
|
||||
103.151.192.0/23 permit
|
||||
103.168.172.128/27 permit
|
||||
103.237.104.0/22 permit
|
||||
@@ -1385,9 +1370,6 @@
|
||||
117.120.16.0/21 permit
|
||||
119.42.242.52/31 permit
|
||||
119.42.242.156 permit
|
||||
121.244.91.48 permit
|
||||
121.244.91.52 permit
|
||||
122.15.156.182 permit
|
||||
123.126.78.64/29 permit
|
||||
124.108.96.24/31 permit
|
||||
124.108.96.28/31 permit
|
||||
@@ -1470,21 +1452,7 @@
|
||||
134.170.141.64/26 permit
|
||||
134.170.143.0/24 permit
|
||||
134.170.174.0/24 permit
|
||||
135.84.80.0/24 permit
|
||||
135.84.81.0/24 permit
|
||||
135.84.82.0/24 permit
|
||||
135.84.83.0/24 permit
|
||||
135.84.216.0/22 permit
|
||||
136.143.160.0/24 permit
|
||||
136.143.161.0/24 permit
|
||||
136.143.162.0/24 permit
|
||||
136.143.176.0/24 permit
|
||||
136.143.177.0/24 permit
|
||||
136.143.178.49 permit
|
||||
136.143.182.0/23 permit
|
||||
136.143.184.0/24 permit
|
||||
136.143.188.0/24 permit
|
||||
136.143.190.0/23 permit
|
||||
136.146.128.0/20 permit
|
||||
136.147.128.0/20 permit
|
||||
136.147.135.0/24 permit
|
||||
@@ -1504,7 +1472,6 @@
|
||||
139.138.46.219 permit
|
||||
139.138.57.55 permit
|
||||
139.138.58.119 permit
|
||||
139.167.79.86 permit
|
||||
139.177.108.0/25 permit
|
||||
139.180.17.0/24 permit
|
||||
140.238.148.191 permit
|
||||
@@ -1554,12 +1521,14 @@
|
||||
147.243.128.26 permit
|
||||
148.105.0.0/16 permit
|
||||
148.105.8.0/21 permit
|
||||
148.116.32.128/25 permit
|
||||
149.72.0.0/16 permit
|
||||
149.72.234.184 permit
|
||||
149.72.248.236 permit
|
||||
149.97.173.180 permit
|
||||
149.118.160.128/25 permit
|
||||
150.136.21.199 permit
|
||||
150.171.109.118 permit
|
||||
150.230.98.160 permit
|
||||
151.145.38.14 permit
|
||||
152.67.105.195 permit
|
||||
@@ -1636,11 +1605,6 @@
|
||||
164.152.25.241 permit
|
||||
164.177.132.168/30 permit
|
||||
165.1.100.0/25 permit
|
||||
165.173.128.0/24 permit
|
||||
165.173.180.1 permit
|
||||
165.173.180.250/31 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
|
||||
@@ -1673,19 +1637,6 @@
|
||||
168.245.12.252 permit
|
||||
168.245.46.9 permit
|
||||
168.245.127.231 permit
|
||||
169.148.129.0/24 permit
|
||||
169.148.131.0/24 permit
|
||||
169.148.138.0/24 permit
|
||||
169.148.142.10 permit
|
||||
169.148.142.33 permit
|
||||
169.148.144.0/25 permit
|
||||
169.148.144.10 permit
|
||||
169.148.146.0/23 permit
|
||||
169.148.174.10 permit
|
||||
169.148.175.3 permit
|
||||
169.148.179.3 permit
|
||||
169.148.188.0/24 permit
|
||||
169.148.188.182 permit
|
||||
170.9.232.254 permit
|
||||
170.10.128.0/24 permit
|
||||
170.10.129.0/24 permit
|
||||
@@ -1891,16 +1842,7 @@
|
||||
199.16.156.0/22 permit
|
||||
199.33.145.1 permit
|
||||
199.33.145.32 permit
|
||||
199.34.22.36 permit
|
||||
199.59.148.0/22 permit
|
||||
199.67.80.2 permit
|
||||
199.67.80.20 permit
|
||||
199.67.82.2 permit
|
||||
199.67.82.20 permit
|
||||
199.67.84.0/24 permit
|
||||
199.67.86.0/24 permit
|
||||
199.67.88.0/24 permit
|
||||
199.67.90.0/24 permit
|
||||
199.101.161.130 permit
|
||||
199.101.162.0/25 permit
|
||||
199.122.120.0/21 permit
|
||||
@@ -1956,8 +1898,6 @@
|
||||
204.92.114.187 permit
|
||||
204.92.114.203 permit
|
||||
204.92.114.204/31 permit
|
||||
204.141.32.0/23 permit
|
||||
204.141.42.0/23 permit
|
||||
204.216.164.202 permit
|
||||
204.220.160.0/21 permit
|
||||
204.220.168.0/21 permit
|
||||
@@ -2231,10 +2171,7 @@
|
||||
2001:748:400:3301::4 permit
|
||||
2404:6800:4000::/36 permit
|
||||
2404:6800:4864::/56 permit
|
||||
2603:1061:14:72::1 permit
|
||||
2607:13c0:0001:0000:0000:0000:0000:7000/116 permit
|
||||
2607:13c0:0002:0000:0000:0000:0000:1000/116 permit
|
||||
2607:13c0:0004:0000:0000:0000:0000:0000/116 permit
|
||||
2603:1061:14:40::1 permit
|
||||
2607:f8b0:4000::/36 permit
|
||||
2607:f8b0:4864::/56 permit
|
||||
2620:109:c003:104::/64 permit
|
||||
|
||||
@@ -3,8 +3,7 @@ rules {
|
||||
backend = "http";
|
||||
url = "http://nginx:9081/pipe.php";
|
||||
selector = "reject_no_global_bl";
|
||||
formatter = "default";
|
||||
meta_headers = true;
|
||||
formatter = "multipart";
|
||||
}
|
||||
RLINFO {
|
||||
backend = "http";
|
||||
@@ -16,8 +15,7 @@ rules {
|
||||
backend = "http";
|
||||
url = "http://nginx:9081/pushover.php";
|
||||
selector = "mailcow_rcpt";
|
||||
formatter = "json";
|
||||
meta_headers = true;
|
||||
formatter = "multipart";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,47 +32,42 @@ function parse_email($email) {
|
||||
$a = strrpos($email, '@');
|
||||
return array('local' => substr($email, 0, $a), 'domain' => substr(substr($email, $a), 1));
|
||||
}
|
||||
if (!function_exists('getallheaders')) {
|
||||
function getallheaders() {
|
||||
if (!is_array($_SERVER)) {
|
||||
return array();
|
||||
}
|
||||
$headers = array();
|
||||
foreach ($_SERVER as $name => $value) {
|
||||
if (substr($name, 0, 5) == 'HTTP_') {
|
||||
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
|
||||
}
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
// rspamd metadata_exporter (multipart formatter):
|
||||
// - $_POST['metadata'] JSON with the rspamd metadata
|
||||
// - $_FILES['message'] raw RFC822 message
|
||||
if (empty($_POST['metadata']) || !isset($_FILES['message']) || $_FILES['message']['error'] !== UPLOAD_ERR_OK) {
|
||||
error_log("QUARANTINE: missing multipart parts from rspamd" . PHP_EOL);
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
$raw_data_content = file_get_contents('php://input');
|
||||
$meta = json_decode($_POST['metadata'], true);
|
||||
if (!is_array($meta)) {
|
||||
error_log("QUARANTINE: cannot decode metadata JSON" . PHP_EOL);
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
$raw_data_content = file_get_contents($_FILES['message']['tmp_name']);
|
||||
$raw_data = mb_convert_encoding($raw_data_content, 'HTML-ENTITIES', "UTF-8");
|
||||
$headers = getallheaders();
|
||||
$raw_size = (int)$_FILES['message']['size'];
|
||||
|
||||
$qid = $headers['X-Rspamd-Qid'];
|
||||
$fuzzy = $headers['X-Rspamd-Fuzzy'];
|
||||
$subject = iconv_mime_decode($headers['X-Rspamd-Subject']);
|
||||
$score = $headers['X-Rspamd-Score'];
|
||||
$rcpts = $headers['X-Rspamd-Rcpt'];
|
||||
$user = $headers['X-Rspamd-User'];
|
||||
$ip = $headers['X-Rspamd-Ip'];
|
||||
$action = $headers['X-Rspamd-Action'];
|
||||
$sender = $headers['X-Rspamd-From'];
|
||||
$symbols = $headers['X-Rspamd-Symbols'];
|
||||
|
||||
$raw_size = (int)$_SERVER['CONTENT_LENGTH'];
|
||||
$qid = $meta['qid'] ?? 'unknown';
|
||||
$subject = iconv_mime_decode($meta['subject'] ?? '');
|
||||
$score = $meta['score'] ?? 0;
|
||||
$rcpts = $meta['rcpt'] ?? array();
|
||||
$user = $meta['user'] ?? 'unknown';
|
||||
$ip = $meta['ip'] ?? 'unknown';
|
||||
$action = $meta['action'] ?? 'no action';
|
||||
$sender = $meta['from'] ?? '';
|
||||
$symbols = json_encode($meta['symbols'] ?? array());
|
||||
$fuzzy = json_encode(is_array($meta['fuzzy'] ?? null) ? $meta['fuzzy'] : array());
|
||||
|
||||
if (empty($sender)) {
|
||||
error_log("QUARANTINE: Unknown sender, assuming empty-env-from@localhost" . PHP_EOL);
|
||||
$sender = 'empty-env-from@localhost';
|
||||
}
|
||||
|
||||
if ($fuzzy == 'unknown') {
|
||||
$fuzzy = '[]';
|
||||
}
|
||||
|
||||
try {
|
||||
$max_size = (int)$redis->Get('Q_MAX_SIZE');
|
||||
if (($max_size * 1048576) < $raw_size) {
|
||||
@@ -94,7 +89,7 @@ catch (RedisException $e) {
|
||||
$rcpt_final_mailboxes = array();
|
||||
|
||||
// Loop through all rcpts
|
||||
foreach (json_decode($rcpts, true) as $rcpt) {
|
||||
foreach ($rcpts as $rcpt) {
|
||||
// Remove tag
|
||||
$rcpt = preg_replace('/^(.*?)\+.*(@.*)$/', '$1$2', $rcpt);
|
||||
|
||||
|
||||
@@ -32,50 +32,46 @@ function parse_email($email) {
|
||||
$a = strrpos($email, '@');
|
||||
return array('local' => substr($email, 0, $a), 'domain' => substr(substr($email, $a), 1));
|
||||
}
|
||||
if (!function_exists('getallheaders')) {
|
||||
function getallheaders() {
|
||||
if (!is_array($_SERVER)) {
|
||||
return array();
|
||||
}
|
||||
$headers = array();
|
||||
foreach ($_SERVER as $name => $value) {
|
||||
if (substr($name, 0, 5) == 'HTTP_') {
|
||||
$headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
|
||||
}
|
||||
}
|
||||
return $headers;
|
||||
}
|
||||
// rspamd metadata_exporter (multipart formatter): metadata JSON arrives as $_POST['metadata'].
|
||||
if (empty($_POST['metadata'])) {
|
||||
error_log("NOTIFY: missing metadata part from rspamd" . PHP_EOL);
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
$headers = getallheaders();
|
||||
$json_body = json_decode(file_get_contents('php://input'));
|
||||
$meta = json_decode($_POST['metadata'], true);
|
||||
if (!is_array($meta)) {
|
||||
error_log("NOTIFY: cannot decode metadata JSON" . PHP_EOL);
|
||||
http_response_code(400);
|
||||
exit;
|
||||
}
|
||||
|
||||
$qid = $headers['X-Rspamd-Qid'];
|
||||
$rcpts = $headers['X-Rspamd-Rcpt'];
|
||||
$sender = $headers['X-Rspamd-From'];
|
||||
$ip = $headers['X-Rspamd-Ip'];
|
||||
$subject = iconv_mime_decode($headers['X-Rspamd-Subject']);
|
||||
$messageid= $json_body->message_id;
|
||||
$qid = $meta['qid'] ?? 'unknown';
|
||||
$rcpts = $meta['rcpt'] ?? array();
|
||||
$sender = $meta['from'] ?? '';
|
||||
$ip = $meta['ip'] ?? 'unknown';
|
||||
$subject = iconv_mime_decode($meta['subject'] ?? '');
|
||||
$messageid= $meta['message_id'] ?? '';
|
||||
$priority = 0;
|
||||
|
||||
$symbols_array = json_decode($headers['X-Rspamd-Symbols'], true);
|
||||
$symbols_array = $meta['symbols'] ?? array();
|
||||
if (is_array($symbols_array)) {
|
||||
foreach ($symbols_array as $symbol) {
|
||||
if ($symbol['name'] == 'HAS_X_PRIO_ONE') {
|
||||
if (($symbol['name'] ?? null) == 'HAS_X_PRIO_ONE') {
|
||||
$priority = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sender_address = $json_body->header_from[0];
|
||||
$sender_address = $meta['header_from'][0] ?? '';
|
||||
$sender_name = '-';
|
||||
if (preg_match('/(?<name>.*?)<(?<address>.*?)>/i', $sender_address, $matches)) {
|
||||
$sender_address = $matches['address'];
|
||||
$sender_name = trim($matches['name'], '"\' ');
|
||||
}
|
||||
|
||||
$to_address = $json_body->header_to[0];
|
||||
$to_address = $meta['header_to'][0] ?? '';
|
||||
$to_name = '-';
|
||||
if (preg_match('/(?<name>.*?)<(?<address>.*?)>/i', $to_address, $matches)) {
|
||||
$to_address = $matches['address'];
|
||||
@@ -85,7 +81,7 @@ if (preg_match('/(?<name>.*?)<(?<address>.*?)>/i', $to_address, $matches)) {
|
||||
$rcpt_final_mailboxes = array();
|
||||
|
||||
// Loop through all rcpts
|
||||
foreach (json_decode($rcpts, true) as $rcpt) {
|
||||
foreach ($rcpts as $rcpt) {
|
||||
// Remove tag
|
||||
$rcpt = preg_replace('/^(.*?)\+.*(@.*)$/', '$1$2', $rcpt);
|
||||
|
||||
|
||||
@@ -1072,6 +1072,7 @@ paths:
|
||||
password2: "*"
|
||||
quota: "3072"
|
||||
force_pw_update: "1"
|
||||
force_tfa: "1"
|
||||
tls_enforce_in: "1"
|
||||
tls_enforce_out: "1"
|
||||
tags: ["tag1", "tag2"]
|
||||
@@ -1118,6 +1119,7 @@ paths:
|
||||
password2: atedismonsin
|
||||
quota: "3072"
|
||||
force_pw_update: "1"
|
||||
force_tfa: "1"
|
||||
tls_enforce_in: "1"
|
||||
tls_enforce_out: "1"
|
||||
tags: ["tag1", "tag2"]
|
||||
@@ -1151,6 +1153,9 @@ paths:
|
||||
force_pw_update:
|
||||
description: forces the user to update its password on first login
|
||||
type: boolean
|
||||
force_tfa:
|
||||
description: force 2FA enrollment at login
|
||||
type: boolean
|
||||
tls_enforce_in:
|
||||
description: force inbound email tls encryption
|
||||
type: boolean
|
||||
@@ -2510,7 +2515,7 @@ paths:
|
||||
description: >-
|
||||
Using this endpoint you can perform actions on quarantine items. It is possible to release
|
||||
emails from quarantine into to the inbox, or learn them as ham to improve Rspamd filtering.
|
||||
You must provide the quarantine item IDs. You can get the IDs using the GET method.
|
||||
You must provide the quarantine item IDs. You can get the IDs using the GET method.
|
||||
operationId: Edit mails in Quarantine
|
||||
requestBody:
|
||||
content:
|
||||
@@ -3414,6 +3419,7 @@ paths:
|
||||
- mailbox
|
||||
- active: "1"
|
||||
force_pw_update: "0"
|
||||
force_tfa: "0"
|
||||
name: Full name
|
||||
password: "*"
|
||||
password2: "*"
|
||||
@@ -3464,6 +3470,7 @@ paths:
|
||||
attr:
|
||||
active: "1"
|
||||
force_pw_update: "0"
|
||||
force_tfa: "0"
|
||||
name: Full name
|
||||
authsource: mailcow
|
||||
password: ""
|
||||
@@ -3487,6 +3494,9 @@ paths:
|
||||
force_pw_update:
|
||||
description: force user to change password on next login
|
||||
type: boolean
|
||||
force_tfa:
|
||||
description: force 2FA enrollment at login
|
||||
type: boolean
|
||||
name:
|
||||
description: Full name of the mailbox user
|
||||
type: string
|
||||
@@ -4881,6 +4891,7 @@ paths:
|
||||
- active: "1"
|
||||
attributes:
|
||||
force_pw_update: "0"
|
||||
force_tfa: "0"
|
||||
mailbox_format: "maildir:"
|
||||
quarantine_notification: never
|
||||
sogo_access: "1"
|
||||
@@ -5805,6 +5816,7 @@ paths:
|
||||
- active: "1"
|
||||
attributes:
|
||||
force_pw_update: "0"
|
||||
force_tfa: "0"
|
||||
mailbox_format: "maildir:"
|
||||
quarantine_notification: never
|
||||
sogo_access: "1"
|
||||
|
||||
@@ -3505,7 +3505,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
// Track affected mailboxes for SOGo update
|
||||
$update_sogo_mailboxes[] = $username;
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
case 'mailbox_rename':
|
||||
$domain = $_data['domain'];
|
||||
@@ -3828,6 +3827,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
$attr["rl_frame"] = (!empty($_data['rl_frame'])) ? $_data['rl_frame'] : $is_now['rl_frame'];
|
||||
$attr["rl_value"] = (!empty($_data['rl_value'])) ? $_data['rl_value'] : $is_now['rl_value'];
|
||||
$attr["force_pw_update"] = isset($_data['force_pw_update']) ? intval($_data['force_pw_update']) : $is_now['force_pw_update'];
|
||||
$attr["force_tfa"] = isset($_data['force_tfa']) ? intval($_data['force_tfa']) : $is_now['force_tfa'];
|
||||
$attr["sogo_access"] = isset($_data['sogo_access']) ? intval($_data['sogo_access']) : $is_now['sogo_access'];
|
||||
$attr["active"] = isset($_data['active']) ? intval($_data['active']) : $is_now['active'];
|
||||
$attr["tls_enforce_in"] = isset($_data['tls_enforce_in']) ? intval($_data['tls_enforce_in']) : $is_now['tls_enforce_in'];
|
||||
@@ -6127,7 +6127,6 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
|
||||
// Track affected mailboxes for SOGo update
|
||||
$update_sogo_mailboxes[] = $username;
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
case 'mailbox_templates':
|
||||
if ($_SESSION['mailcow_cc_role'] != "admin") {
|
||||
|
||||
@@ -424,6 +424,11 @@ $(document).ready(function() {
|
||||
} else {
|
||||
$('#force_pw_update').prop('checked', false);
|
||||
}
|
||||
if (template.force_tfa == 1){
|
||||
$('#force_tfa').prop('checked', true);
|
||||
} else {
|
||||
$('#force_tfa').prop('checked', false);
|
||||
}
|
||||
if (template.sogo_access == 1){
|
||||
$('#sogo_access').prop('checked', true);
|
||||
} else {
|
||||
@@ -1242,6 +1247,7 @@ jQuery(function($){
|
||||
item.attributes.eas_access = '<i class="text-' + (item.attributes.eas_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.eas_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.eas_access == 1 ? '1' : '0') + '</span></i>';
|
||||
item.attributes.dav_access = '<i class="text-' + (item.attributes.dav_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.dav_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.dav_access == 1 ? '1' : '0') + '</span></i>';
|
||||
item.attributes.sogo_access = '<i class="text-' + (item.attributes.sogo_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.sogo_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.sogo_access == 1 ? '1' : '0') + '</span></i>';
|
||||
item.attributes.force_tfa = '<i class="text-' + (item.attributes.force_tfa == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.force_tfa == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.force_tfa == 1 ? '1' : '0') + '</span></i>';
|
||||
if (item.attributes.quarantine_notification === 'never') {
|
||||
item.attributes.quarantine_notification = lang.never;
|
||||
} else if (item.attributes.quarantine_notification === 'hourly') {
|
||||
@@ -1385,6 +1391,11 @@ jQuery(function($){
|
||||
return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
|
||||
}
|
||||
},
|
||||
{
|
||||
title: lang.force_tfa,
|
||||
data: 'attributes.force_tfa',
|
||||
defaultContent: ''
|
||||
},
|
||||
{
|
||||
title: lang_edit.ratelimit,
|
||||
data: 'attributes.ratelimit',
|
||||
|
||||
@@ -929,6 +929,7 @@
|
||||
"filters": "Filters",
|
||||
"fname": "Full name",
|
||||
"force_pw_update": "Force password update at next login",
|
||||
"force_tfa": "TFA",
|
||||
"gal": "Global Address List",
|
||||
"goto_ham": "Learn as <b>ham</b>",
|
||||
"goto_spam": "Learn as <b>spam</b>",
|
||||
|
||||
@@ -65,6 +65,7 @@ if (isset($_GET['app_password'])) {
|
||||
$attr['protocols'][] = 'dav_access';
|
||||
}
|
||||
app_passwd("add", $attr);
|
||||
$password = htmlspecialchars($password, ENT_NOQUOTES);
|
||||
} else {
|
||||
$app_password = false;
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
<input type="hidden" value="default" name="sender_acl">
|
||||
<input type="hidden" value="0" name="force_pw_update">
|
||||
<input type="hidden" value="0" name="force_tfa">
|
||||
<input type="hidden" value="0" name="sogo_access">
|
||||
<input type="hidden" value="0" name="protocol_access">
|
||||
|
||||
@@ -165,6 +166,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="offset-sm-2 col-sm-10">
|
||||
<div class="form-check">
|
||||
<label><input type="checkbox" class="form-check-input" value="1" name="force_tfa" id="force_tfa"{% if template.attributes.force_tfa == '1' %} checked{% endif %}> {{ lang.tfa.force_tfa }}</label>
|
||||
<small class="text-muted">{{ lang.tfa.force_tfa_info }}</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if not skip_sogo %}
|
||||
<div class="row">
|
||||
<div class="offset-sm-2 col-sm-10">
|
||||
|
||||
+3
-3
@@ -84,7 +84,7 @@ services:
|
||||
- clamd
|
||||
|
||||
rspamd-mailcow:
|
||||
image: ghcr.io/mailcow/rspamd:3.14.3-1
|
||||
image: ghcr.io/mailcow/rspamd:4.1.0-1
|
||||
stop_grace_period: 30s
|
||||
depends_on:
|
||||
- dovecot-mailcow
|
||||
@@ -117,7 +117,7 @@ services:
|
||||
- rspamd
|
||||
|
||||
php-fpm-mailcow:
|
||||
image: ghcr.io/mailcow/phpfpm:8.2.29-2
|
||||
image: ghcr.io/mailcow/phpfpm:8.2.29-3
|
||||
command: "php-fpm -d date.timezone=${TZ} -d expose_php=0"
|
||||
depends_on:
|
||||
- redis-mailcow
|
||||
@@ -200,7 +200,7 @@ services:
|
||||
- phpfpm
|
||||
|
||||
sogo-mailcow:
|
||||
image: ghcr.io/mailcow/sogo:5.12.8-1
|
||||
image: ghcr.io/mailcow/sogo:5.12.9-1
|
||||
environment:
|
||||
- DBNAME=${DBNAME}
|
||||
- DBUSER=${DBUSER}
|
||||
|
||||
+1
-1
@@ -25,6 +25,6 @@ services:
|
||||
- /var/run/mysqld/mysqld.sock:/var/run/mysqld/mysqld.sock
|
||||
|
||||
mysql-mailcow:
|
||||
image: alpine:3.23
|
||||
image: alpine:3.24
|
||||
command: /bin/true
|
||||
restart: "no"
|
||||
|
||||
Reference in New Issue
Block a user