diff --git a/data/Dockerfiles/dockerapi/dockerapi.py b/data/Dockerfiles/dockerapi/dockerapi.py index 6d3b1012..63436b62 100644 --- a/data/Dockerfiles/dockerapi/dockerapi.py +++ b/data/Dockerfiles/dockerapi/dockerapi.py @@ -9,6 +9,7 @@ import os import json import asyncio import redis +import platform from datetime import datetime import logging from logging.config import dictConfig @@ -381,11 +382,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 @@ -482,7 +486,8 @@ async def get_host_stats(wait=5): "swap": psutil.swap_memory() }, "uptime": time.time() - psutil.boot_time(), - "system_time": system_time.strftime("%d.%m.%Y %H:%M:%S") + "system_time": system_time.strftime("%d.%m.%Y %H:%M:%S"), + "architecture": platform.machine() } redis_client.set('host_stats', json.dumps(host_stats), ex=10) diff --git a/data/web/css/build/011-datatables.css b/data/web/css/build/011-datatables.css index d03514ff..d262f07c 100644 --- a/data/web/css/build/011-datatables.css +++ b/data/web/css/build/011-datatables.css @@ -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; } diff --git a/data/web/css/site/mailbox.css b/data/web/css/site/mailbox.css index f62ead31..e896abca 100644 --- a/data/web/css/site/mailbox.css +++ b/data/web/css/site/mailbox.css @@ -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; +} diff --git a/data/web/css/themes/mailcow-darkmode.css b/data/web/css/themes/mailcow-darkmode.css index 6e0db0e9..abaa7499 100644 --- a/data/web/css/themes/mailcow-darkmode.css +++ b/data/web/css/themes/mailcow-darkmode.css @@ -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; } @@ -299,22 +304,22 @@ a:hover { } -table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before:hover, +table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before:hover, table.dataTable.dtr-inline.collapsed>tbody>tr>th.dtr-control:before:hover { background-color: #7a7a7a !important; } -table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before, +table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before, table.dataTable.dtr-inline.collapsed>tbody>tr>th.dtr-control:before { background-color: #7a7a7a !important; border: 1.5px solid #5c5c5c !important; color: #fff !important; } -table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td.dtr-control:before, +table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td.dtr-control:before, table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th.dtr-control:before { background-color: #949494; } -table.dataTable.dtr-inline.collapsed>tbody>tr>td.child, -table.dataTable.dtr-inline.collapsed>tbody>tr>th.child, +table.dataTable.dtr-inline.collapsed>tbody>tr>td.child, +table.dataTable.dtr-inline.collapsed>tbody>tr>th.child, table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty { background-color: #444444; } @@ -327,7 +332,7 @@ table.dataTable.dtr-inline.collapsed>tbody>tr>td.dataTables_empty { } .btn.btn-outline-secondary { color: #fff !important; - border-color: #7a7a7a !important; + border-color: #7a7a7a !important; } .btn-check:checked+.btn-outline-secondary, .btn-check:active+.btn-outline-secondary, .btn-outline-secondary:active, .btn-outline-secondary.active, .btn-outline-secondary.dropdown-toggle.show { background-color: #9b9b9b !important; diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index de1855fa..4dc2418c 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -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) { diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 4529ee7b..4e036b99 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -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(); } } diff --git a/data/web/js/site/admin.js b/data/web/js/site/admin.js index 23ef1d25..07dfed8c 100644 --- a/data/web/js/site/admin.js +++ b/data/web/js/site/admin.js @@ -117,8 +117,8 @@ jQuery(function($){ data: 'tfa_active', defaultContent: '', render: function (data, type) { - if(data == 1) return ''; - else return ''; + if(data == 1) return '1'; + else return '0'; } }, { @@ -126,8 +126,8 @@ jQuery(function($){ data: 'active', defaultContent: '', render: function (data, type) { - if(data == 1) return ''; - else return ''; + if(data == 1) return '1'; + else return '0'; } }, { @@ -260,8 +260,8 @@ jQuery(function($){ data: 'tfa_active', defaultContent: '', render: function (data, type) { - if(data == 1) return ''; - else return ''; + if(data == 1) return '1'; + else return '0'; } }, { @@ -269,8 +269,8 @@ jQuery(function($){ data: 'active', defaultContent: '', render: function (data, type) { - if(data == 1) return ''; - else return ''; + if(data == 1) return '1'; + else return '0'; } }, { @@ -337,7 +337,7 @@ jQuery(function($){ data: 'keep_spam', defaultContent: '', render: function(data, type){ - return 'yes'==data?'':'no'==data&&''; + return 'yes'==data?'yes':'no'==data&&'no'; } }, { @@ -414,8 +414,8 @@ jQuery(function($){ data: 'active', defaultContent: '', render: function (data, type) { - if(data == 1) return ''; - else return ''; + if(data == 1) return '1'; + else return '0'; } }, { @@ -492,8 +492,8 @@ jQuery(function($){ data: 'active', defaultContent: '', render: function (data, type) { - if(data == 1) return ''; - else return ''; + if(data == 1) return '1'; + else return '0'; } }, { diff --git a/data/web/js/site/debug.js b/data/web/js/site/debug.js index 55b6660b..78a4ccaa 100644 --- a/data/web/js/site/debug.js +++ b/data/web/js/site/debug.js @@ -43,7 +43,7 @@ $(document).ready(function() { if (mailcow_info.branch === "master"){ check_update(mailcow_info.version_tag, mailcow_info.project_url); } - $("#maiclow_version").click(function(){ + $("#mailcow_version").click(function(){ if (mailcow_cc_role !== "admin" && mailcow_cc_role !== "domainadmin" || mailcow_info.branch !== "master") return; @@ -1302,6 +1302,12 @@ function update_stats(timeout=5){ $("#host_cpu_usage").text(parseInt(data.cpu.usage).toString() + "%"); $("#host_memory_total").text((data.memory.total / (1024 ** 3)).toFixed(2).toString() + "GB"); $("#host_memory_usage").text(parseInt(data.memory.usage).toString() + "%"); + if (data.architecture == "aarch64"){ + $("#host_architecture").html('' + data.architecture + ' ⚠️'); + } + else { + $("#host_architecture").html(data.architecture); + } // update cpu and mem chart var cpu_chart = Chart.getChart("host_cpu_chart"); diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index f4039268..d7fca848 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -607,7 +607,7 @@ jQuery(function($){ defaultContent: '', responsivePriority: 6, render: function (data, type) { - return 1==data?'':(0==data?'':2==data&&'—'); + return 1==data?'1':(0==data?'0':2==data&&'—'); } }, { @@ -754,7 +754,7 @@ jQuery(function($){ data: 'attributes.gal', defaultContent: '', render: function (data, type) { - return 1==data?'':''; + return 1==data?'1':'0'; } }, { @@ -762,7 +762,7 @@ jQuery(function($){ data: 'attributes.backupmx', defaultContent: '', render: function (data, type) { - return 1==data?'':''; + return 1==data?'1':'0'; } }, { @@ -770,7 +770,7 @@ jQuery(function($){ data: 'attributes.relay_all_recipients', defaultContent: '', render: function (data, type) { - return 1==data?'':''; + return 1==data?'1':'0'; } }, { @@ -778,7 +778,7 @@ jQuery(function($){ data: 'attributes.relay_unknown_only', defaultContent: '', render: function (data, type) { - return 1==data?'':''; + return 1==data?'1':'0'; } }, { @@ -787,7 +787,7 @@ jQuery(function($){ defaultContent: '', responsivePriority: 4, render: function (data, type) { - return 1==data?'':''; + return 1==data?'1':'0'; } }, { @@ -1093,7 +1093,7 @@ jQuery(function($){ defaultContent: '', responsivePriority: 4, render: function (data, type) { - return 1==data?'':(0==data?'':2==data&&'—'); + return 1==data?'1':(0==data?'0':2==data&&'—'); } }, { @@ -1164,13 +1164,13 @@ jQuery(function($){ item.attributes.quota = humanFileSize(item.attributes.quota); - item.attributes.tls_enforce_in = ''; - item.attributes.tls_enforce_out = ''; - item.attributes.pop3_access = ''; - item.attributes.imap_access = ''; - item.attributes.smtp_access = ''; - item.attributes.sieve_access = ''; - item.attributes.sogo_access = ''; + item.attributes.tls_enforce_in = '' + (item.attributes.tls_enforce_in == 1 ? '1' : '0') + ''; + item.attributes.tls_enforce_out = '' + (item.attributes.tls_enforce_out == 1 ? '1' : '0') + ''; + item.attributes.pop3_access = '' + (item.attributes.pop3_access == 1 ? '1' : '0') + ''; + item.attributes.imap_access = '' + (item.attributes.imap_access == 1 ? '1' : '0') + ''; + item.attributes.smtp_access = '' + (item.attributes.smtp_access == 1 ? '1' : '0') + ''; + item.attributes.sieve_access = '' + (item.attributes.sieve_access == 1 ? '1' : '0') + ''; + item.attributes.sogo_access = '' + (item.attributes.sogo_access == 1 ? '1' : '0') + ''; 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 = '
.*google\\.com
směřuje veškerou poštu na MX které jsou cílem pro google.com přes tento skok)",
+ "lookup_mx": "Cíl je regulární výraz který se shoduje s MX záznamem (.*\\.google\\.com
směřuje veškerou poštu na MX které jsou cílem pro google.com přes tento skok)",
"mailbox": "Úprava mailové schránky",
"mailbox_quota_def": "Výchozí kvóta schránky",
"mailbox_relayhost_info": "Aplikované jen na uživatelskou schránku a přímé aliasy, přepisuje předávající server domény.",
diff --git a/data/web/lang/lang.de-de.json b/data/web/lang/lang.de-de.json
index 4bd4b3fa..6b280bbb 100644
--- a/data/web/lang/lang.de-de.json
+++ b/data/web/lang/lang.de-de.json
@@ -216,7 +216,7 @@
"loading": "Bitte warten...",
"login_time": "Zeit",
"logo_info": "Die hochgeladene Grafik wird für die Navigationsleiste auf eine Höhe von 40px skaliert. Für die Darstellung auf der Login-Maske beträgt die skalierte Breite maximal 250px. Eine frei skalierbare Grafik (etwa SVG) wird empfohlen.",
- "lookup_mx": "Ziel mit MX vergleichen (Regex, etwa .*google\\.com
, um alle Ziele mit MX *google.com zu routen)",
+ "lookup_mx": "Ziel mit MX vergleichen (Regex, etwa .*\\.google\\.com
, um alle Ziele mit MX *google.com zu routen)",
"main_name": "\"mailcow UI\" Name",
"merged_vars_hint": "Ausgegraute Reihen wurden aus der Datei vars.(local.)inc.php
gelesen und können hier nicht verändert werden.",
"message": "Nachricht",
@@ -498,6 +498,7 @@
}
},
"debug": {
+ "architecture": "Architektur",
"chart_this_server": "Chart (dieser Server)",
"containers_info": "Container-Information",
"container_running": "Läuft",
@@ -534,7 +535,8 @@
"update_available": "Es ist ein Update verfügbar",
"no_update_available": "Das System ist auf aktuellem Stand",
"update_failed": "Es konnte nicht nach einem Update gesucht werden",
- "username": "Benutzername"
+ "username": "Benutzername",
+ "wip": "Aktuell noch in Arbeit"
},
"diagnostics": {
"cname_from_a": "Wert abgeleitet von A/AAAA-Eintrag. Wird unterstützt, sofern der Eintrag auf die korrekte Ressource zeigt.",
@@ -593,7 +595,7 @@
"inactive": "Inaktiv",
"kind": "Art",
"last_modified": "Zuletzt geändert",
- "lookup_mx": "Ziel mit MX vergleichen (Regex, etwa .*google\\.com
, um alle Ziele mit MX *google.com zu routen)",
+ "lookup_mx": "Ziel mit MX vergleichen (Regex, etwa .*\\.google\\.com
, um alle Ziele mit MX *google.com zu routen)",
"mailbox": "Mailbox bearbeiten",
"mailbox_quota_def": "Standard-Quota einer Mailbox",
"mailbox_relayhost_info": "Wird auf eine Mailbox und direkte Alias-Adressen angewendet. Überschreibt die Einstellung einer Domain.",
diff --git a/data/web/lang/lang.en-gb.json b/data/web/lang/lang.en-gb.json
index df83987c..e53fe896 100644
--- a/data/web/lang/lang.en-gb.json
+++ b/data/web/lang/lang.en-gb.json
@@ -218,7 +218,7 @@
"loading": "Please wait...",
"login_time": "Login time",
"logo_info": "Your image will be scaled to a height of 40px for the top navigation bar and a max. width of 250px for the start page. A scalable graphic is highly recommended.",
- "lookup_mx": "Destination is a regular expression to match against MX name (.*google\\.com
to route all mail targeted to a MX ending in google.com over this hop)",
+ "lookup_mx": "Destination is a regular expression to match against MX name (.*\\.google\\.com
to route all mail targeted to a MX ending in google.com over this hop)",
"main_name": "\"mailcow UI\" name",
"merged_vars_hint": "Greyed out rows were merged from vars.(local.)inc.php
and cannot be modified.",
"message": "Message",
@@ -498,6 +498,7 @@
}
},
"debug": {
+ "architecture": "Architecture",
"chart_this_server": "Chart (this server)",
"containers_info": "Container information",
"container_running": "Running",
@@ -534,7 +535,8 @@
"update_available": "There is an update available",
"no_update_available": "The System is on the latest version",
"update_failed": "Could not check for an Update",
- "username": "Username"
+ "username": "Username",
+ "wip": "Currently Work in Progress"
},
"diagnostics": {
"cname_from_a": "Value derived from A/AAAA record. This is supported as long as the record points to the correct resource.",
@@ -593,7 +595,7 @@
"inactive": "Inactive",
"kind": "Kind",
"last_modified": "Last modified",
- "lookup_mx": "Destination is a regular expression to match against MX name (.*google\\.com
to route all mail targeted to a MX ending in google.com over this hop)",
+ "lookup_mx": "Destination is a regular expression to match against MX name (.*\\.google\\.com
to route all mail targeted to a MX ending in google.com over this hop)",
"mailbox": "Edit mailbox",
"mailbox_quota_def": "Default mailbox quota",
"mailbox_relayhost_info": "Applied to the mailbox and direct aliases only, does override a domain relayhost.",
diff --git a/data/web/lang/lang.fr-fr.json b/data/web/lang/lang.fr-fr.json
index d64f62f7..0bc0ba02 100644
--- a/data/web/lang/lang.fr-fr.json
+++ b/data/web/lang/lang.fr-fr.json
@@ -588,7 +588,7 @@
"unchanged_if_empty": "Si non modifié, laisser en blanc",
"username": "Nom d'utilisateur",
"validate_save": "Valider et sauver",
- "lookup_mx": "La destination est une expression régulière qui doit correspondre avec le nom du MX (.*google\\.com
pour acheminer tout le courrier destiné à un MX se terminant par google.com via ce saut)",
+ "lookup_mx": "La destination est une expression régulière qui doit correspondre avec le nom du MX (.*\\.google\\.com
pour acheminer tout le courrier destiné à un MX se terminant par google.com via ce saut)",
"mailbox_relayhost_info": "S'applique uniquement à la boîte aux lettres et aux alias directs, remplace le relayhost du domaine."
},
"footer": {
diff --git a/data/web/lang/lang.it-it.json b/data/web/lang/lang.it-it.json
index 4d21547c..0d5b3f25 100644
--- a/data/web/lang/lang.it-it.json
+++ b/data/web/lang/lang.it-it.json
@@ -213,7 +213,7 @@
"loading": "Caricamento in corso...",
"login_time": "Ora di accesso",
"logo_info": "La tua immagine verrà ridimensionata a 40px di altezza, quando verrà usata nella barra di navigazione in alto, ed ad una larghezza massima di 250px nella schermata iniziale. È altamente consigliato l'utilizzo di un'immagine modulabile.",
- "lookup_mx": "Destination is a regular expression to match against MX name (.*google\\.com
to route all mail targeted to a MX ending in google.com over this hop)",
+ "lookup_mx": "Destination is a regular expression to match against MX name (.*\\.google\\.com
to route all mail targeted to a MX ending in google.com over this hop)",
"main_name": "Nome \"mailcow UI\"",
"merged_vars_hint": "Greyed out rows were merged from vars.(local.)inc.php
and cannot be modified.",
"message": "Messaggio",
@@ -554,7 +554,7 @@
"hostname": "Hostname",
"inactive": "Inattivo",
"kind": "Genere",
- "lookup_mx": "Destination is a regular expression to match against MX name (.*google\\.com
to route all mail targeted to a MX ending in google.com over this hop)",
+ "lookup_mx": "Destination is a regular expression to match against MX name (.*\\.google\\.com
to route all mail targeted to a MX ending in google.com over this hop)",
"mailbox": "Modifica casella di posta",
"mailbox_quota_def": "Default mailbox quota",
"mailbox_relayhost_info": "Applied to the mailbox and direct aliases only, does override a domain relayhost.",
diff --git a/data/web/lang/lang.ro-ro.json b/data/web/lang/lang.ro-ro.json
index 8e6e1d45..e6315db0 100644
--- a/data/web/lang/lang.ro-ro.json
+++ b/data/web/lang/lang.ro-ro.json
@@ -539,7 +539,7 @@
"inactive": "Inactiv",
"kind": "Fel",
"last_modified": "Ultima modificare",
- "lookup_mx": "Destinația este o expresie regulată care potrivită cu numele MX (.*google\\.com
pentru a direcționa toate e-mailurile vizate către un MX care se termină în google.com peste acest hop)",
+ "lookup_mx": "Destinația este o expresie regulată care potrivită cu numele MX (.*\\.google\\.com
pentru a direcționa toate e-mailurile vizate către un MX care se termină în google.com peste acest hop)",
"mailbox": "Editează căsuța poștală",
"mailbox_quota_def": "Cota implicită a căsuței poștale",
"mailbox_relayhost_info": "Aplicat numai căsuței poștale și aliasurilor directe, suprascrie un transport dependent de domeniu.",
diff --git a/data/web/lang/lang.ru-ru.json b/data/web/lang/lang.ru-ru.json
index 65dd4bae..bad64184 100644
--- a/data/web/lang/lang.ru-ru.json
+++ b/data/web/lang/lang.ru-ru.json
@@ -336,7 +336,9 @@
"validate_license_now": "Получить лицензию на основе GUID с сервера лицензий",
"verify": "Проверить",
"yes": "✓",
- "queue_unban": "разблокировать"
+ "queue_unban": "разблокировать",
+ "f2b_ban_time_increment": "Время бана увеличивается с каждым баном",
+ "f2b_max_ban_time": "Максимальное время блокировки"
},
"danger": {
"access_denied": "Доступ запрещён, или указаны неверные данные",
diff --git a/data/web/lang/lang.sk-sk.json b/data/web/lang/lang.sk-sk.json
index 2b93650f..29b36c44 100644
--- a/data/web/lang/lang.sk-sk.json
+++ b/data/web/lang/lang.sk-sk.json
@@ -213,7 +213,7 @@
"loading": "Čakajte prosím ...",
"login_time": "Čas prihlásenia",
"logo_info": "Váš obrázok bude upravený na výšku 40px pre vrchný navigačný riadok a na maximálnu šírku 250px pre úvodnú stránku. Odporúča sa škálovateľná grafika.",
- "lookup_mx": "Cieľ je regulárny výraz ktorý sa porovnáva s MX záznamom (.*google\\.com
smeruje všetku poštu určenú pre MX ktoré sú cieľom pre google.com cez tento skok)",
+ "lookup_mx": "Cieľ je regulárny výraz ktorý sa porovnáva s MX záznamom (.*\\.google\\.com
smeruje všetku poštu určenú pre MX ktoré sú cieľom pre google.com cez tento skok)",
"main_name": "\"mailcow UI\" názov",
"merged_vars_hint": "Sivé riadky boli načítané z vars.(local.)inc.php
a nemôžu byť modifikované cez UI.",
"message": "Správa",
@@ -539,7 +539,7 @@
"inactive": "Neaktívny",
"kind": "Druh",
"last_modified": "Naposledy upravené",
- "lookup_mx": "Cieľ je regulárny výraz ktorý sa zhoduje s MX záznamom (.*google\\.com
smeruje všetku poštu na MX ktoré sú cieľom pre google.com cez tento skok)",
+ "lookup_mx": "Cieľ je regulárny výraz ktorý sa zhoduje s MX záznamom (.*\\.google\\.com
smeruje všetku poštu na MX ktoré sú cieľom pre google.com cez tento skok)",
"mailbox": "Upraviť mailovú schránku",
"mailbox_quota_def": "Predvolená veľkosť mailovej schránky",
"mailbox_relayhost_info": "Aplikované len na používateľské schránky a priame aliasy, prepisuje doménového preposielateľa.",
diff --git a/data/web/lang/lang.zh-cn.json b/data/web/lang/lang.zh-cn.json
index e57ea2a7..90888efd 100644
--- a/data/web/lang/lang.zh-cn.json
+++ b/data/web/lang/lang.zh-cn.json
@@ -213,7 +213,7 @@
"loading": "请等待...",
"login_time": "登录时间",
"logo_info": "你的图片将会在顶部导航栏被缩放为 40px 高,在起始页被缩放为最大 250px 高。强烈推荐使用能较好适应缩放的图片。",
- "lookup_mx": "应当为一个正则表达式,用于匹配 MX 记录 (例如 .*google\\.com
将转发所有拥有以 google.com 结尾的 MX 记录的邮件)",
+ "lookup_mx": "应当为一个正则表达式,用于匹配 MX 记录 (例如 .*\\.google\\.com
将转发所有拥有以 google.com 结尾的 MX 记录的邮件)",
"main_name": "Mailcow UI 的名称",
"merged_vars_hint": "灰色行来自 vars.(local.)inc.php
文件并且无法修改。",
"message": "消息",
@@ -544,7 +544,7 @@
"hostname": "主机名",
"inactive": "禁用",
"kind": "类型",
- "lookup_mx": "应当为一个正则表达式,用于匹配 MX 记录 (例如 .*google\\.com
将转发所有拥有以 google.com 结尾的 MX 记录的邮件)",
+ "lookup_mx": "应当为一个正则表达式,用于匹配 MX 记录 (例如 .*\\.google\\.com
将转发所有拥有以 google.com 结尾的 MX 记录的邮件)",
"mailbox": "编辑邮箱",
"mailbox_quota_def": "邮箱默认配额",
"mailbox_relayhost_info": "只适用于邮箱和邮箱别名,不会覆盖域名的中继主机。",
diff --git a/data/web/lang/lang.zh-tw.json b/data/web/lang/lang.zh-tw.json
index 916188db..ff9ed334 100644
--- a/data/web/lang/lang.zh-tw.json
+++ b/data/web/lang/lang.zh-tw.json
@@ -213,7 +213,7 @@
"loading": "請稍等...",
"login_time": "登入時間",
"logo_info": "你的起始頁面圖片會在頂部導覽列的限制下被縮放為 40px 高,以及最大 250px 高度。強烈推薦使用能較好縮放的圖片。",
- "lookup_mx": "目的地是可以用來匹配 MX 紀錄的正規表達式 (.*google\\.com
會將所有 MX 結尾於 google.com 的郵件轉發到此主機。)",
+ "lookup_mx": "目的地是可以用來匹配 MX 紀錄的正規表達式 (.*\\.google\\.com
會將所有 MX 結尾於 google.com 的郵件轉發到此主機。)",
"main_name": "\"mailcow UI\" 名稱",
"merged_vars_hint": "灰色列來自 vars.(local.)inc.php
並且不能修改。",
"message": "訊息",
@@ -540,7 +540,7 @@
"inactive": "停用",
"kind": "種類",
"last_modified": "上次修改時間",
- "lookup_mx": "目的地是可以用來匹配 MX 紀錄的正規表達式 (.*google\\.com
會將所有 MX 結尾於 google.com 的郵件轉發到此主機。)",
+ "lookup_mx": "目的地是可以用來匹配 MX 紀錄的正規表達式 (.*\\.google\\.com
會將所有 MX 結尾於 google.com 的郵件轉發到此主機。)",
"mailbox": "編輯信箱",
"mailbox_quota_def": "預設信箱容量配額",
"mailbox_relayhost_info": "只會套用於信箱和直接別名,不會覆寫域名中繼主機。",
diff --git a/data/web/sogo-auth.php b/data/web/sogo-auth.php
index 7ca5e4d9..40fff585 100644
--- a/data/web/sogo-auth.php
+++ b/data/web/sogo-auth.php
@@ -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;
}
}
diff --git a/data/web/templates/debug.twig b/data/web/templates/debug.twig
index d24d7ed6..adc19b26 100644
--- a/data/web/templates/debug.twig
+++ b/data/web/templates/debug.twig
@@ -49,6 +49,12 @@
{{ hostname }}
-
+