Compare commits

...

45 Commits

Author SHA1 Message Date
Patrick Schult
8f28666916 Merge pull request #5195 from mailcow/staging
2023-04b
2023-04-20 16:49:17 +02:00
Patrick Schult
3eaa5a626c Merge pull request #5187 from mailcow/fix-5185
Nextcloud helperscript - redo PHP check
2023-04-20 14:20:03 +02:00
Patrick Schult
8c79056a94 Merge pull request #5194 from mailcow/renovate/nextcloud-server-26.x
Update dependency nextcloud/server to v26.0.1
2023-04-20 14:19:19 +02:00
Patrick Schult
ed076dc23e Merge pull request #5186 from goodygh/datatables_sorting
[Web] Datatables sorting
2023-04-20 13:50:57 +02:00
FreddleSpl0it
be2286c11c [Dockerapi] fix maildir cleanup for domains 2023-04-20 13:41:11 +02:00
renovate[bot]
0e24c3d300 Update dependency nextcloud/server to v26.0.1
Signed-off-by: milkmaker <milkmaker@mailcow.de>
2023-04-20 11:36:01 +00:00
FreddleSpl0it
e1d8df6580 [Web] check mailbox before replacing sogo_static_view 2023-04-20 13:20:51 +02:00
Patrick Schult
04a08a7d69 Merge pull request #5193 from mailcow/feat/update-sogo
[SOGo] update sogo 5.8.2.20230419
2023-04-20 12:32:42 +02:00
FreddleSpl0it
3c0c8aa01f [SOGo] update sogo 5.8.2.20230419 2023-04-20 12:07:21 +02:00
Patrick Schult
026b278357 Merge pull request #5183 from mailcow/fix/add-mbox-performance
[Web] optimizing mailbox add/edit/delete performance
2023-04-20 11:34:41 +02:00
FreddleSpl0it
4121509ceb [Web] optimizing update_sogo_static_view function 2023-04-20 11:28:59 +02:00
Patrick Schult
00ac61f0a4 Merge pull request #5184 from bdwebnet/fix/ui-allowed-protocols
Added dropdown divider to "allowed protocols" selection on mailbox page
2023-04-19 17:31:05 +02:00
Patrick Schult
4bb0dbb2f7 Merge pull request #5191 from shiz0/patch-1
Fix Typo
2023-04-19 17:26:54 +02:00
Patrick Schult
13b6df74af Merge pull request #5174 from bdwebnet/staging
Fix error  "Deprecated: Using ${var} in strings is deprecated, use {$…
2023-04-19 17:23:26 +02:00
FreddleSpl0it
5c025bf865 [Rspamd] rollback to 3.4 2023-04-19 17:03:04 +02:00
Hannes Happle
20fc9eaf84 Fix Typo 2023-04-16 14:32:44 +02:00
Peter
22a0479fab Redo the PHP check grep 2023-04-13 21:11:40 +02:00
goodygh
3510d5617d Fix sorting for active relayhost 2023-04-13 19:18:04 +02:00
goodygh
236d627fbd Fix sorting for active transport map 2023-04-13 19:14:20 +02:00
goodygh
99739eada0 Fix sorting for active fowrardinghoststable 2023-04-13 19:01:03 +02:00
goodygh
7bfef57894 Fix sorting for active and tla on admins 2023-04-13 18:54:59 +02:00
goodygh
d9dfe15253 Fix sorting for active and tla on domain-admins 2023-04-13 18:54:08 +02:00
goodygh
3fe8aaa719 Fix sorting for active tls-policy-map 2023-04-13 18:14:18 +02:00
goodygh
78a8fac6af Fix sorting for active bcc-map and recipient-map 2023-04-13 18:10:21 +02:00
bd
6986e7758f Added dropdown divider to "allowed protocols" selection on mailbox page 2023-04-13 17:33:28 +02:00
BD
b4a9df76b8 Merge branch 'mailcow:staging' into staging 2023-04-13 17:22:13 +02:00
FreddleSpl0it
d9d958356a [Web] optimizing update_sogo_static_view function 2023-04-13 14:35:55 +02:00
goodygh
96f954a4e2 Fix sorting for active syncjobs 2023-04-12 00:36:46 +02:00
goodygh
44585e1c15 Fix sorting datatable in domain aliases 2023-04-12 00:23:53 +02:00
goodygh
c737ff4180 Fix sorting datatable in aliases 2023-04-12 00:21:27 +02:00
goodygh
025279009d Fix sorting for active resources 2023-04-12 00:17:41 +02:00
goodygh
a9dc13d567 Fix sorting datatable in mailbox templates 2023-04-12 00:15:16 +02:00
goodygh
c3ed01c9b5 Fix sorting for active mailboxes 2023-04-11 23:49:50 +02:00
goodygh
bd0b4a521e Fix sorting datatable in domain templates 2023-04-11 23:42:43 +02:00
goodygh
800a0ace71 Fix sorting for active domain in domains table 2023-04-11 23:19:56 +02:00
goodygh
db97869472 Datatable hide sorting value 2023-04-11 23:18:13 +02:00
milkmaker
f681fcf154 [Web] Updated lang.cs-cz.json (#5177)
Co-authored-by: utaxiu <kontakt@malyjakub.cz>
2023-04-11 17:38:39 +02:00
Patrick Schult
db1b5956fc Merge pull request #5133 from FELDSAM-INC/feldsam/bs5-related-fixes
BS5 related fixes
2023-04-11 06:35:41 +02:00
BD
bdb07061ed Fix error "Deprecated: Using ${var} in strings is deprecated, use {$var} instead in /web/sogo-auth.php on line 63" 2023-04-08 17:29:34 +02:00
Niklas Meyer
428b917579 Merge pull request #5166 from mailcow/staging
Hotfix php8.2 nextcloud < 26
2023-04-03 20:15:46 +02:00
Niklas Meyer
469f959e96 Merge pull request #5164 from mailcow/fix-5163
Add a check for PHP>=8.2 errormsg
2023-04-03 20:10:05 +02:00
Peter
b68e189d97 Add a check for PHP>=8.2 errormsg 2023-04-03 19:03:13 +02:00
Kristian Feldsam
80dacc015a [web] fixed mailbox/user settings buttons styling
Signed-off-by: Kristian Feldsam <feldsam@gmail.com>

[web] fixed mailbox/user settings buttons styling

Signed-off-by: Kristian Feldsam <feldsam@gmail.com>
2023-03-31 13:19:20 +02:00
Kristian Feldsam
e5e6418be8 [web] fixed tooltips in ajax loaded alias table
Signed-off-by: Kristian Feldsam <feldsam@gmail.com>
2023-03-20 01:38:34 +01:00
Kristian Feldsam
6507b53bbb [web] fix mailbox badge height
Signed-off-by: Kristian Feldsam <feldsam@gmail.com>
2023-03-20 01:38:31 +01:00
16 changed files with 162 additions and 89 deletions

View File

@@ -381,11 +381,14 @@ class DockerUtils:
for container in self.docker_client.containers.list(filters={"id": container_id}):
sane_name = re.sub(r'\W+', '', request_json['maildir'])
vmail_name = request_json['maildir'].replace("'", "'\\''")
index_name = request_json['maildir'].split("/")
index_name = index_name[1].replace("'", "'\\''") + "@" + index_name[0].replace("'", "'\\''")
cmd_vmail = "if [[ -d '/var/vmail/" + vmail_name + "' ]]; then /bin/mv '/var/vmail/" + vmail_name + "' '/var/vmail/_garbage/" + str(int(time.time())) + "_" + sane_name + "'; fi"
cmd_vmail_index = "if [[ -d '/var/vmail_index/" + index_name + "' ]]; then /bin/mv '/var/vmail_index/" + index_name + "' '/var/vmail/_garbage/" + str(int(time.time())) + "_" + sane_name + "_index'; fi"
cmd = ["/bin/bash", "-c", cmd_vmail + " && " + cmd_vmail_index]
index_name = request_json['maildir'].split("/")
if len(index_name) > 1:
index_name = index_name[1].replace("'", "'\\''") + "@" + index_name[0].replace("'", "'\\''")
cmd_vmail_index = "if [[ -d '/var/vmail_index/" + index_name + "' ]]; then /bin/mv '/var/vmail_index/" + index_name + "' '/var/vmail/_garbage/" + str(int(time.time())) + "_" + sane_name + "_index'; fi"
cmd = ["/bin/bash", "-c", cmd_vmail + " && " + cmd_vmail_index]
else:
cmd = ["/bin/bash", "-c", cmd_vmail]
maildir_cleanup = container.exec_run(cmd, user='vmail')
return exec_run_handler('generic', maildir_cleanup)
# api call: container_post - post_action: exec - cmd: rspamd - task: worker_password

View File

@@ -342,6 +342,10 @@ div.dataTables_wrapper div.dt-row {
position: relative;
}
div.dataTables_wrapper span.sorting-value {
display: none;
}
div.dataTables_scrollHead table.dataTable {
margin-bottom: 0 !important;
}

View File

@@ -66,4 +66,6 @@ table tbody tr td input[type="checkbox"] {
padding: .2em .4em .3em !important;
background-color: #ececec!important;
}
.badge.bg-info .bi {
font-size: inherit;
}

View File

@@ -20,6 +20,11 @@ legend {
background-color: #7a7a7a !important;
border-color: #5c5c5c !important;
}
.btn-dark {
color: #000 !important;;
background-color: #f6f6f6 !important;;
border-color: #ddd !important;;
}
.btn-check:checked+.btn-secondary, .btn-check:active+.btn-secondary, .btn-secondary:active, .btn-secondary.active, .show>.btn-secondary.dropdown-toggle {
border-color: #7a7a7a !important;
}

View File

@@ -1015,20 +1015,58 @@ function formatBytes($size, $precision = 2) {
}
return round(pow(1024, $base - floor($base)), $precision) . $suffixes[floor($base)];
}
function update_sogo_static_view() {
function update_sogo_static_view($mailbox = null) {
if (getenv('SKIP_SOGO') == "y") {
return true;
}
global $pdo;
global $lang;
$stmt = $pdo->query("SELECT 'OK' FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME = 'sogo_view'");
$num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC));
if ($num_results != 0) {
$stmt = $pdo->query("REPLACE INTO _sogo_static_view (`c_uid`, `domain`, `c_name`, `c_password`, `c_cn`, `mail`, `aliases`, `ad_aliases`, `ext_acl`, `kind`, `multiple_bookings`)
SELECT `c_uid`, `domain`, `c_name`, `c_password`, `c_cn`, `mail`, `aliases`, `ad_aliases`, `ext_acl`, `kind`, `multiple_bookings` from sogo_view");
$stmt = $pdo->query("DELETE FROM _sogo_static_view WHERE `c_uid` NOT IN (SELECT `username` FROM `mailbox` WHERE `active` = '1');");
$mailbox_exists = false;
if ($mailbox !== null) {
// Check if the mailbox exists
$stmt = $pdo->prepare("SELECT username FROM mailbox WHERE username = :mailbox AND active = '1'");
$stmt->execute(array(':mailbox' => $mailbox));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row){
$mailbox_exists = true;
}
}
$query = "REPLACE INTO _sogo_static_view (`c_uid`, `domain`, `c_name`, `c_password`, `c_cn`, `mail`, `aliases`, `ad_aliases`, `ext_acl`, `kind`, `multiple_bookings`)
SELECT
mailbox.username,
mailbox.domain,
mailbox.username,
IF(JSON_UNQUOTE(JSON_VALUE(attributes, '$.force_pw_update')) = '0',
IF(JSON_UNQUOTE(JSON_VALUE(attributes, '$.sogo_access')) = 1, password, '{SSHA256}A123A123A321A321A321B321B321B123B123B321B432F123E321123123321321'),
'{SSHA256}A123A123A321A321A321B321B321B123B123B321B432F123E321123123321321'),
mailbox.name,
mailbox.username,
IFNULL(GROUP_CONCAT(ga.aliases ORDER BY ga.aliases SEPARATOR ' '), ''),
IFNULL(gda.ad_alias, ''),
IFNULL(external_acl.send_as_acl, ''),
mailbox.kind,
mailbox.multiple_bookings
FROM
mailbox
LEFT OUTER JOIN grouped_mail_aliases ga ON ga.username REGEXP CONCAT('(^|,)', mailbox.username, '($|,)')
LEFT OUTER JOIN grouped_domain_alias_address gda ON gda.username = mailbox.username
LEFT OUTER JOIN grouped_sender_acl_external external_acl ON external_acl.username = mailbox.username
WHERE
mailbox.active = '1'";
if ($mailbox_exists) {
$query .= " AND mailbox.username = :mailbox";
$stmt = $pdo->prepare($query);
$stmt->execute(array(':mailbox' => $mailbox));
} else {
$query .= " GROUP BY mailbox.username";
$stmt = $pdo->query($query);
}
$stmt = $pdo->query("DELETE FROM _sogo_static_view WHERE `c_uid` NOT IN (SELECT `username` FROM `mailbox` WHERE `active` = '1');");
flush_memcached();
}
function edit_user_account($_data) {

View File

@@ -1264,11 +1264,13 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
));
}
update_sogo_static_view($username);
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('mailbox_added', htmlspecialchars($username))
);
return true;
break;
case 'resource':
$domain = idn_to_ascii(strtolower(trim($_data['domain'])), 0, INTL_IDNA_VARIANT_UTS46);
@@ -3130,7 +3132,10 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('mailbox_modified', $username)
);
update_sogo_static_view($username);
}
return true;
break;
case 'mailbox_templates':
if ($_SESSION['mailcow_cc_role'] != "admin") {
@@ -5053,12 +5058,15 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
);
continue;
}
update_sogo_static_view($username);
$_SESSION['return'][] = array(
'type' => 'success',
'log' => array(__FUNCTION__, $_action, $_type, $_data_log, $_attr),
'msg' => array('mailbox_removed', htmlspecialchars($username))
);
}
return true;
break;
case 'mailbox_templates':
if ($_SESSION['mailcow_cc_role'] != "admin") {
@@ -5264,7 +5272,7 @@ function mailbox($_action, $_type, $_data = null, $_extra = null) {
}
break;
}
if ($_action != 'get' && in_array($_type, array('domain', 'alias', 'alias_domain', 'mailbox', 'resource')) && getenv('SKIP_SOGO') != "y") {
if ($_action != 'get' && in_array($_type, array('domain', 'alias', 'alias_domain', 'resource')) && getenv('SKIP_SOGO') != "y") {
update_sogo_static_view();
}
}

View File

@@ -117,8 +117,8 @@ jQuery(function($){
data: 'tfa_active',
defaultContent: '',
render: function (data, type) {
if(data == 1) return '<i class="bi bi-check-lg"></i>';
else return '<i class="bi bi-x-lg"></i>';
if(data == 1) return '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -126,8 +126,8 @@ jQuery(function($){
data: 'active',
defaultContent: '',
render: function (data, type) {
if(data == 1) return '<i class="bi bi-check-lg"></i>';
else return '<i class="bi bi-x-lg"></i>';
if(data == 1) return '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -260,8 +260,8 @@ jQuery(function($){
data: 'tfa_active',
defaultContent: '',
render: function (data, type) {
if(data == 1) return '<i class="bi bi-check-lg"></i>';
else return '<i class="bi bi-x-lg"></i>';
if(data == 1) return '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -269,8 +269,8 @@ jQuery(function($){
data: 'active',
defaultContent: '',
render: function (data, type) {
if(data == 1) return '<i class="bi bi-check-lg"></i>';
else return '<i class="bi bi-x-lg"></i>';
if(data == 1) return '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -337,7 +337,7 @@ jQuery(function($){
data: 'keep_spam',
defaultContent: '',
render: function(data, type){
return 'yes'==data?'<i class="bi bi-x-lg"></i>':'no'==data&&'<i class="bi bi-check-lg"></i>';
return 'yes'==data?'<i class="bi bi-x-lg"><span class="sorting-value">yes</span></i>':'no'==data&&'<i class="bi bi-check-lg"><span class="sorting-value">no</span></i>';
}
},
{
@@ -414,8 +414,8 @@ jQuery(function($){
data: 'active',
defaultContent: '',
render: function (data, type) {
if(data == 1) return '<i class="bi bi-check-lg"></i>';
else return '<i class="bi bi-x-lg"></i>';
if(data == 1) return '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -492,8 +492,8 @@ jQuery(function($){
data: 'active',
defaultContent: '',
render: function (data, type) {
if(data == 1) return '<i class="bi bi-check-lg"></i>';
else return '<i class="bi bi-x-lg"></i>';
if(data == 1) return '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{

View File

@@ -607,7 +607,7 @@ jQuery(function($){
defaultContent: '',
responsivePriority: 6,
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':(0==data?'<i class="bi bi-x-lg"></i>':2==data&&'&#8212;');
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':(0==data?'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>':2==data&&'&#8212;');
}
},
{
@@ -754,7 +754,7 @@ jQuery(function($){
data: 'attributes.gal',
defaultContent: '',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -762,7 +762,7 @@ jQuery(function($){
data: 'attributes.backupmx',
defaultContent: '',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -770,7 +770,7 @@ jQuery(function($){
data: 'attributes.relay_all_recipients',
defaultContent: '',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -778,7 +778,7 @@ jQuery(function($){
data: 'attributes.relay_unknown_only',
defaultContent: '',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -787,7 +787,7 @@ jQuery(function($){
defaultContent: '',
responsivePriority: 4,
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -1093,7 +1093,7 @@ jQuery(function($){
defaultContent: '',
responsivePriority: 4,
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':(0==data?'<i class="bi bi-x-lg"></i>':2==data&&'&#8212;');
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':(0==data?'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>':2==data&&'&#8212;');
}
},
{
@@ -1164,13 +1164,13 @@ jQuery(function($){
item.attributes.quota = humanFileSize(item.attributes.quota);
item.attributes.tls_enforce_in = '<i class="text-' + (item.attributes.tls_enforce_in == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"></i>';
item.attributes.tls_enforce_out = '<i class="text-' + (item.attributes.tls_enforce_out == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"></i>';
item.attributes.pop3_access = '<i class="text-' + (item.attributes.pop3_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.pop3_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
item.attributes.imap_access = '<i class="text-' + (item.attributes.imap_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.imap_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
item.attributes.smtp_access = '<i class="text-' + (item.attributes.smtp_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.smtp_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
item.attributes.sieve_access = '<i class="text-' + (item.attributes.sieve_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.sieve_access == 1 ? 'check-lg' : 'x-lg') + '"></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') + '"></i>';
item.attributes.tls_enforce_in = '<i class="text-' + (item.attributes.tls_enforce_in == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"><span class="sorting-value">' + (item.attributes.tls_enforce_in == 1 ? '1' : '0') + '</span></i>';
item.attributes.tls_enforce_out = '<i class="text-' + (item.attributes.tls_enforce_out == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"><span class="sorting-value">' + (item.attributes.tls_enforce_out == 1 ? '1' : '0') + '</span></i>';
item.attributes.pop3_access = '<i class="text-' + (item.attributes.pop3_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.pop3_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.pop3_access == 1 ? '1' : '0') + '</span></i>';
item.attributes.imap_access = '<i class="text-' + (item.attributes.imap_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.imap_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.imap_access == 1 ? '1' : '0') + '</span></i>';
item.attributes.smtp_access = '<i class="text-' + (item.attributes.smtp_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.smtp_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.smtp_access == 1 ? '1' : '0') + '</span></i>';
item.attributes.sieve_access = '<i class="text-' + (item.attributes.sieve_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.sieve_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.sieve_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>';
if (item.attributes.quarantine_notification === 'never') {
item.attributes.quarantine_notification = lang.never;
} else if (item.attributes.quarantine_notification === 'hourly') {
@@ -1188,7 +1188,6 @@ jQuery(function($){
item.attributes.quarantine_category = lang.q_all;
}
if (item.template.toLowerCase() == "default"){
item.action = '<div class="btn-group">' +
'<a href="/edit/template/' + encodeURIComponent(item.id) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
@@ -1329,7 +1328,7 @@ jQuery(function($){
defaultContent: '',
responsivePriority: 4,
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':(0==data?'<i class="bi bi-x-lg"></i>':2==data&&'&#8212;');
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':(0==data?'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>':2==data&&'&#8212;');
}
},
{
@@ -1440,7 +1439,7 @@ jQuery(function($){
data: 'active',
defaultContent: '',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':(0==data?'<i class="bi bi-x-lg"></i>':2==data&&'&#8212;');
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':(0==data?'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>':2==data&&'&#8212;');
}
},
{
@@ -1578,7 +1577,7 @@ jQuery(function($){
data: 'active',
defaultContent: '',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':(0==data?'<i class="bi bi-x-lg"></i>':2==data&&'&#8212;');
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':(0==data?'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>':2==data&&'&#8212;');
}
},
{
@@ -1675,7 +1674,7 @@ jQuery(function($){
data: 'active',
defaultContent: '',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -1782,7 +1781,7 @@ jQuery(function($){
data: 'active',
defaultContent: '',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -1917,7 +1916,7 @@ jQuery(function($){
data: 'sogo_visible',
defaultContent: '',
render: function(data, type){
return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -1936,7 +1935,7 @@ jQuery(function($){
defaultContent: '',
responsivePriority: 6,
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -1952,6 +1951,10 @@ jQuery(function($){
table.on('responsive-resize', function (e, datatable, columns){
hideTableExpandCollapseBtn('#tab-mbox-aliases', '#alias_table');
});
table.on( 'draw', function (){
$('#alias_table [data-bs-toggle="tooltip"]').tooltip();
});
}
function draw_aliasdomain_table() {
// just recalc width if instance already exists
@@ -2031,7 +2034,7 @@ jQuery(function($){
data: 'active',
defaultContent: '',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{
@@ -2167,7 +2170,7 @@ jQuery(function($){
data: 'active',
defaultContent: '',
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
}
},
{

View File

@@ -105,7 +105,8 @@
"timeout2": "Časový limit pro připojení k lokálnímu serveru",
"username": "Uživatelské jméno",
"validate": "Ověřit",
"validation_success": "Úspěšně ověřeno"
"validation_success": "Úspěšně ověřeno",
"tags": "Štítky"
},
"admin": {
"access": "Přístupy",
@@ -333,7 +334,11 @@
"username": "Uživatelské jméno",
"validate_license_now": "Ověřit GUID na licenčním serveru",
"verify": "Ověřit",
"yes": "&#10003;"
"yes": "&#10003;",
"f2b_ban_time_increment": "Délka banu je prodlužována s každým dalším banem",
"f2b_max_ban_time": "Maximální délka banu (s)",
"ip_check": "Kontrola IP",
"ip_check_disabled": "Kontrola IP je vypnuta. Můžete ji zapnout v <br> <strong>System > Nastavení > Options > Přizpůsobení</strong>"
},
"danger": {
"access_denied": "Přístup odepřen nebo jsou neplatná data ve formuláři",

View File

@@ -60,7 +60,7 @@ elseif (isset($_GET['login'])) {
':remote_addr' => ($_SERVER['HTTP_X_REAL_IP'] ?? $_SERVER['REMOTE_ADDR'])
));
// redirect to sogo (sogo will get the correct credentials via nginx auth_request
header("Location: /SOGo/so/${login}");
header("Location: /SOGo/so/{$login}");
exit;
}
}

View File

@@ -109,25 +109,25 @@
<label class="control-label col-sm-2">{{ lang.user.quarantine_notification }}</label>
<div class="col-sm-10">
<div class="btn-group" data-acl="{{ acl.quarantine_notification }}">
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-secondary{% if quarantine_notification == 'never' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light{% if quarantine_notification == 'never' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_notification"
data-api-url='edit/quarantine_notification'
data-api-attr='{"quarantine_notification":"never"}'>{{ lang.user.never }}</button>
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-secondary{% if quarantine_notification == 'hourly' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light{% if quarantine_notification == 'hourly' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_notification"
data-api-url='edit/quarantine_notification'
data-api-attr='{"quarantine_notification":"hourly"}'>{{ lang.user.hourly }}</button>
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-secondary{% if quarantine_notification == 'daily' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light{% if quarantine_notification == 'daily' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_notification"
data-api-url='edit/quarantine_notification'
data-api-attr='{"quarantine_notification":"daily"}'>{{ lang.user.daily }}</button>
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-secondary{% if quarantine_notification == 'weekly' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light{% if quarantine_notification == 'weekly' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_notification"
@@ -141,19 +141,19 @@
<label class="control-label col-sm-2">{{ lang.user.quarantine_category }}</label>
<div class="col-sm-10">
<div class="btn-group" data-acl="{{ acl.quarantine_category }}">
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-secondary{% if quarantine_category == 'reject' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-light{% if quarantine_category == 'reject' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_category"
data-api-url='edit/quarantine_category'
data-api-attr='{"quarantine_category":"reject"}'>{{ lang.user.q_reject }}</button>
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-secondary{% if quarantine_category == 'add_header' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-light{% if quarantine_category == 'add_header' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_category"
data-api-url='edit/quarantine_category'
data-api-attr='{"quarantine_category":"add_header"}'>{{ lang.user.q_add_header }}</button>
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-secondary{% if quarantine_category == 'all' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-light{% if quarantine_category == 'all' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="quarantine_category"
@@ -167,13 +167,13 @@
<label class="control-label col-sm-2" for="sender_acl">{{ lang.user.tls_policy }}</label>
<div class="col-sm-10">
<div class="btn-group" data-acl="{{ acl.tls_policy }}">
<button type="button" class="btn btn-sm btn-xs-half d-block d-sm-inline btn-secondary{% if get_tls_policy.tls_enforce_in == '1' %} active"{% endif %}"
<button type="button" class="btn btn-sm btn-xs-half d-block d-sm-inline btn-light{% if get_tls_policy.tls_enforce_in == '1' %} btn-dark"{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="tls_policy"
data-api-url='edit/tls_policy'
data-api-attr='{"tls_enforce_in": {% if get_tls_policy.tls_enforce_in == '1' %}0{% else %}1{% endif %} }'>{{ lang.user.tls_enforce_in }}</button>
<button type="button" class="btn btn-sm btn-xs-half d-block d-sm-inline btn-secondary{% if get_tls_policy.tls_enforce_out == '1' %} active"{% endif %}"
<button type="button" class="btn btn-sm btn-xs-half d-block d-sm-inline btn-light{% if get_tls_policy.tls_enforce_out == '1' %} btn-dark"{% endif %}"
data-action="edit_selected"
data-item="{{ mailbox }}"
data-id="tls_policy"

View File

@@ -54,6 +54,7 @@
<li class="dropdown-header">SMTP</li>
<li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"smtp_access":1}' href="#">{{ lang.mailbox.activate }}</a></li>
<li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"smtp_access":0}' href="#">{{ lang.mailbox.deactivate }}</a></li>
<li><hr class="dropdown-divider"></li>
<li class="dropdown-header">Sieve</li>
<li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"sieve_access":1}' href="#">{{ lang.mailbox.activate }}</a></li>
<li><a class="dropdown-item" data-action="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"sieve_access":0}' href="#">{{ lang.mailbox.deactivate }}</a></li>

View File

@@ -12,19 +12,19 @@
<div class="col-sm-3 col-12 text-sm-end text-start text-xs-bold mb-4">{{ lang.user.tag_handling }}:</div>
<div class="col-sm-9 col-12">
<div class="btn-group" data-acl="{{ acl.delimiter_action }}">
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-secondary{% if get_tagging_options == 'subfolder' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-light{% if get_tagging_options == 'subfolder' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
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 btn-secondary{% if get_tagging_options == 'subject' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-light{% if get_tagging_options == 'subject' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
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 btn-secondary{% if get_tagging_options == 'none' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-light{% if get_tagging_options == 'none' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
data-id="delimiter_action"
@@ -40,13 +40,13 @@
<div class="col-sm-3 col-12 text-sm-end text-start text-xs-bold mb-4">{{ lang.user.tls_policy }}:</div>
<div class="col-sm-9 col-12">
<div class="btn-group" data-acl="{{ acl.tls_policy }}">
<button type="button" class="btn btn-sm btn-xs-half d-block d-sm-inline btn-secondary{% if get_tls_policy.tls_enforce_in == '1' %} active"{% endif %}"
<button type="button" class="btn btn-sm btn-xs-half d-block d-sm-inline btn-light{% if get_tls_policy.tls_enforce_in == '1' %} btn-dark"{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
data-id="tls_policy"
data-api-url='edit/tls_policy'
data-api-attr='{"tls_enforce_in": {% if get_tls_policy.tls_enforce_in == '1' %}0{% else %}1{% endif %} }'>{{ lang.user.tls_enforce_in }}</button>
<button type="button" class="btn btn-sm btn-xs-half d-block d-sm-inline btn-secondary{% if get_tls_policy.tls_enforce_out == '1' %} active"{% endif %}"
<button type="button" class="btn btn-sm btn-xs-half d-block d-sm-inline btn-light{% if get_tls_policy.tls_enforce_out == '1' %} btn-dark"{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
data-id="tls_policy"
@@ -61,25 +61,25 @@
<div class="col-sm-3 col-12 text-sm-end text-start text-xs-bold mb-4">{{ lang.user.quarantine_notification }}:</div>
<div class="col-sm-9 col-12">
<div class="btn-group" data-acl="{{ acl.quarantine_notification }}">
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-secondary{% if quarantine_notification == 'never' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light{% if quarantine_notification == 'never' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
data-id="quarantine_notification"
data-api-url='edit/quarantine_notification'
data-api-attr='{"quarantine_notification":"never"}'>{{ lang.user.never }}</button>
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-secondary{% if quarantine_notification == 'hourly' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light{% if quarantine_notification == 'hourly' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
data-id="quarantine_notification"
data-api-url='edit/quarantine_notification'
data-api-attr='{"quarantine_notification":"hourly"}'>{{ lang.user.hourly }}</button>
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-secondary{% if quarantine_notification == 'daily' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light{% if quarantine_notification == 'daily' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
data-id="quarantine_notification"
data-api-url='edit/quarantine_notification'
data-api-attr='{"quarantine_notification":"daily"}'>{{ lang.user.daily }}</button>
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-secondary{% if quarantine_notification == 'weekly' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-quart d-block d-sm-inline btn-light{% if quarantine_notification == 'weekly' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
data-id="quarantine_notification"
@@ -93,19 +93,19 @@
<div class="col-sm-3 col-12 text-sm-end text-start text-xs-bold mb-4">{{ lang.user.quarantine_category }}:</div>
<div class="col-sm-9 col-12">
<div class="btn-group" data-acl="{{ acl.quarantine_category }}">
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-secondary{% if quarantine_category == 'reject' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-light{% if quarantine_category == 'reject' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
data-id="quarantine_category"
data-api-url='edit/quarantine_category'
data-api-attr='{"quarantine_category":"reject"}'>{{ lang.user.q_reject }}</button>
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-secondary{% if quarantine_category == 'add_header' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-light{% if quarantine_category == 'add_header' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
data-id="quarantine_category"
data-api-url='edit/quarantine_category'
data-api-attr='{"quarantine_category":"add_header"}'>{{ lang.user.q_add_header }}</button>
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-secondary{% if quarantine_category == 'all' %} active{% endif %}"
<button type="button" class="btn btn-sm btn-xs-third d-block d-sm-inline btn-light{% if quarantine_category == 'all' %} btn-dark{% endif %}"
data-action="edit_selected"
data-item="{{ mailcow_cc_username }}"
data-id="quarantine_category"

View File

@@ -76,7 +76,7 @@ services:
- clamd
rspamd-mailcow:
image: mailcow/rspamd:1.93
image: mailcow/rspamd:1.92
stop_grace_period: 30s
depends_on:
- dovecot-mailcow
@@ -169,7 +169,7 @@ services:
- phpfpm
sogo-mailcow:
image: mailcow/sogo:1.116
image: mailcow/sogo:1.117
environment:
- DBNAME=${DBNAME}
- DBUSER=${DBUSER}
@@ -510,7 +510,7 @@ services:
- watchdog
dockerapi-mailcow:
image: mailcow/dockerapi:2.02
image: mailcow/dockerapi:2.03
security_opt:
- label=disable
restart: always

View File

@@ -261,7 +261,7 @@ COMPOSE_PROJECT_NAME=mailcowdockerized
# Switch here between native (compose plugin) and standalone
# For more informations take a look at the mailcow docs regarding the configuration options.
# Normally this should be untouched but if you decided to use either of those you can switch it manually here.
# Please be aware that at least one of those variants should be installed on your maschine or mailcow will fail.
# Please be aware that at least one of those variants should be installed on your machine or mailcow will fail.
DOCKER_COMPOSE_VERSION=${COMPOSE_VERSION}

View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# renovate: datasource=github-releases depName=nextcloud/server versioning=semver extractVersion=^v(?<version>.*)$
NEXTCLOUD_VERSION=26.0.0
NEXTCLOUD_VERSION=26.0.1
echo -ne "Checking prerequisites..."
sleep 1
@@ -97,8 +97,12 @@ elif [[ ${NC_UPDATE} == "y" ]]; then
echo -e "\033[31mError: Nextcloud occ not found. Is Nextcloud installed?\033[0m"
exit 1
fi
if ! grep -q 'installed: true' <<<$(docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "/web/nextcloud/occ --no-warnings status"); then
echo "Nextcloud seems not to be installed."
if grep -Pq 'This version of Nextcloud is not compatible with (?:PHP)?(?>=?)(?:PHP)?(?>.+)' <<<$(docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "/web/nextcloud/occ --no-warnings status"); then
echo -e "\033[31mError: This version of Nextcloud is not compatible with the current PHP version of php-fpm-mailcow, we'll fix it\033[0m"
wget -q https://raw.githubusercontent.com/nextcloud/server/v26.0.0/lib/versioncheck.php -O ./data/web/nextcloud/lib/versioncheck.php
echo -e "\e[33mPlease restart the update again.\e[0m"
elif ! grep -q 'installed: true' <<<$(docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "/web/nextcloud/occ --no-warnings status"); then
echo -e "\033[31mError: Nextcloud seems not to be installed.\033[0m"
exit 1
else
docker exec -it -u www-data $(docker ps -f name=php-fpm-mailcow -q) bash -c "php /web/nextcloud/updater/updater.phar"