diff --git a/data/Dockerfiles/dockerapi/dockerapi.py b/data/Dockerfiles/dockerapi/dockerapi.py index 1ce47265..965fc906 100644 --- a/data/Dockerfiles/dockerapi/dockerapi.py +++ b/data/Dockerfiles/dockerapi/dockerapi.py @@ -494,27 +494,14 @@ class DockerUtils: for container in (await self.docker_client.containers.list()): if container._id == container_id: - cmd = "/usr/bin/rspamadm pw -e -p '" + request_json['raw'].replace("'", "'\\''") + "' 2> /dev/null" + cmd = "./set_worker_password.sh '" + request_json['raw'].replace("'", "'\\''") + "' 2> /dev/null" rspamd_password_exec = await container.exec(cmd, user='_rspamd') async with rspamd_password_exec.start(detach=False) as stream: rspamd_password_return = await stream.read_out() - - matched = False - for line in rspamd_password_return.data.decode('utf-8').split("\n"): - if '$2$' in line: - hash = line.strip() - hash_out = re.search('\$2\$.+$', hash).group(0) - rspamd_passphrase_hash = re.sub('[^0-9a-zA-Z\$]+', '', hash_out.rstrip()) - rspamd_password_filename = "/etc/rspamd/override.d/worker-controller-password.inc" - cmd = '''/bin/echo 'enable_password = "%s";' > %s && cat %s''' % (rspamd_passphrase_hash, rspamd_password_filename, rspamd_password_filename) - rspamd_password_exec = await container.exec(cmd, user='_rspamd') - async with rspamd_password_exec.start(detach=False) as stream: - rspamd_password_return = await stream.read_out() - - if rspamd_passphrase_hash.startswith("$2$") and rspamd_passphrase_hash in rspamd_password_return.data.decode('utf-8'): - await container.restart() - matched = True + if "OK" in rspamd_password_return.data.decode('utf-8'): + matched = True + await container.restart() if matched: res = { diff --git a/data/Dockerfiles/rspamd/Dockerfile b/data/Dockerfiles/rspamd/Dockerfile index 23fcbb3f..2520ddcc 100644 --- a/data/Dockerfiles/rspamd/Dockerfile +++ b/data/Dockerfiles/rspamd/Dockerfile @@ -26,6 +26,7 @@ RUN apt-get update && apt-get install -y \ COPY settings.conf /etc/rspamd/settings.conf COPY metadata_exporter.lua /usr/share/rspamd/plugins/metadata_exporter.lua +COPY set_worker_password.sh /set_worker_password.sh COPY docker-entrypoint.sh /docker-entrypoint.sh ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/data/Dockerfiles/rspamd/set_worker_password.sh b/data/Dockerfiles/rspamd/set_worker_password.sh new file mode 100755 index 00000000..7205e888 --- /dev/null +++ b/data/Dockerfiles/rspamd/set_worker_password.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +password_file='/etc/rspamd/override.d/worker-controller-password.inc' +password_hash=`/usr/bin/rspamadm pw -e -p $1` + +echo 'enable_password = "'$password_hash'";' > $password_file + +if grep -q "$password_hash" "$password_file"; then + echo "OK" +else + echo "ERROR" +fi \ No newline at end of file diff --git a/data/web/admin.php b/data/web/admin.php index a68ec033..e53d18fd 100644 --- a/data/web/admin.php +++ b/data/web/admin.php @@ -90,7 +90,6 @@ $template_data = [ 'fido2_cid' => @$_SESSION['fido2_cid'], 'fido2_data' => $fido2_data, 'gal' => @$_SESSION['gal'], - 'license_guid' => license('guid'), 'api' => [ 'ro' => admin_api('ro', 'get'), 'rw' => admin_api('rw', 'get'), diff --git a/data/web/css/build/013-mailcow.css b/data/web/css/build/013-mailcow.css index 9580492d..374d484d 100644 --- a/data/web/css/build/013-mailcow.css +++ b/data/web/css/build/013-mailcow.css @@ -275,23 +275,6 @@ code { font-weight: 600; } -.dataTables_info { - margin: 15px 0 !important; - padding: 0px !important; -} -.dataTables_paginate, .dataTables_length, .dataTables_filter { - margin: 15px 0 !important; -} -.dtr-details { - width: 100%; -} -.dtr-title { - width: 20%; -} -table.dataTable>tbody>tr.child ul.dtr-details>li { - border-bottom: 1px solid rgba(0, 0, 0, 0.129); - padding: 0.5em 0; -} .tag-box { display: flex; @@ -339,42 +322,6 @@ table.dataTable>tbody>tr.child ul.dtr-details>li { padding: 10px; } -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: #5e5e5e; -} -table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before, -table.dataTable.dtr-inline.collapsed>tbody>tr>th.dtr-control:before, -table.dataTable td.dt-control:before { - background-color: #979797 !important; - border: 1.5px solid #616161 !important; - border-radius: 2px !important; - color: #fff; - height: 1em; - width: 1em; - line-height: 1.25em; - border-radius: 0px; - box-shadow: none; - font-size: 14px; - transition: 0.5s all; -} -table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td.dtr-control:before, -table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th.dtr-control:before, -table.dataTable td.dt-control:before { - background-color: #979797 !important; -} -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: #fbfbfb; -} -table.dataTable.table-striped>tbody>tr>td { - vertical-align: middle; -} -table.dataTable.table-striped>tbody>tr>td>input[type="checkbox"] { - margin-top: 7px; -} - .btn-check-label { color: #555; diff --git a/data/web/css/build/015-datatables.css b/data/web/css/build/015-datatables.css new file mode 100644 index 00000000..e5518ff8 --- /dev/null +++ b/data/web/css/build/015-datatables.css @@ -0,0 +1,80 @@ +.dataTables_info { + margin: 15px 0 !important; + padding: 0px !important; +} +.dataTables_paginate, .dataTables_length, .dataTables_filter { + margin: 15px 0 !important; +} +.dtr-details { + width: 100%; +} +.table-striped>tbody>tr:nth-of-type(odd) { + background-color: #F2F2F2; +} +td.child>ul>li { + display: flex; +} +table.dataTable>tbody>tr.child ul.dtr-details>li { + border-bottom: 1px solid rgba(0, 0, 0, 0.129); + padding: 0.5em 0; +} +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: #5e5e5e; +} +table.dataTable.dtr-inline.collapsed>tbody>tr>td.dtr-control:before, +table.dataTable.dtr-inline.collapsed>tbody>tr>th.dtr-control:before, +table.dataTable td.dt-control:before { + background-color: #979797 !important; + border: 1.5px solid #616161 !important; + border-radius: 2px !important; + color: #fff; + height: 1em; + width: 1em; + line-height: 1.25em; + border-radius: 0px; + box-shadow: none; + font-size: 14px; + transition: 0.5s all; +} +table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td.dtr-control:before, +table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th.dtr-control:before, +table.dataTable td.dt-control:before { + background-color: #979797 !important; +} +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: #fbfbfb; +} +table.dataTable.table-striped>tbody>tr>td { + vertical-align: middle; +} +table.dataTable.table-striped>tbody>tr>td>input[type="checkbox"] { + margin-top: 7px; +} +td.dtr-col-lg { + min-width: 350px; + word-break: break-word; +} +td.dtr-col-md { + min-width: 250px; + word-break: break-word; +} +td.dtr-col-sm { + min-width: 125px; + word-break: break-word; +} +.dt-data-w100 .dtr-data { + width: 100%; +} +li .dtr-data { + word-break: break-all; + flex: 1; + padding-left: 5px; + padding-right: 5px; +} +table.dataTable>tbody>tr.child span.dtr-title { + width: 30%; + max-width: 250px; +} \ No newline at end of file diff --git a/data/web/debug.php b/data/web/debug.php index e9b426c4..5618ec00 100644 --- a/data/web/debug.php +++ b/data/web/debug.php @@ -47,21 +47,6 @@ foreach ($containers as $container => $container_info) { // get mailcow data $hostname = getenv('MAILCOW_HOSTNAME'); $timezone = getenv('TZ'); -// get public ips -$curl = curl_init(); -curl_setopt($curl, CURLOPT_URL, 'http://ipv4.mailcow.email'); -curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); -curl_setopt($curl, CURLOPT_POST, 0); -$ipv4 = curl_exec($curl); -curl_setopt($curl, CURLOPT_URL, 'http://ipv6.mailcow.email'); -curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); -curl_setopt($curl, CURLOPT_POST, 0); -$ipv6 = curl_exec($curl); -$ips = array( - "ipv4" => $ipv4, - "ipv6" => $ipv6 -); -curl_close($curl); $template = 'debug.twig'; $template_data = [ @@ -69,7 +54,7 @@ $template_data = [ 'vmail_df' => $vmail_df, 'hostname' => $hostname, 'timezone' => $timezone, - 'ips' => $ips, + 'license_guid' => license('guid'), 'solr_status' => $solr_status, 'solr_uptime' => round($solr_status['status']['dovecot-fts']['uptime'] / 1000 / 60 / 60), 'clamd_status' => $clamd_status, diff --git a/data/web/js/build/012-api.js b/data/web/js/build/012-api.js index b9887940..c657c134 100644 --- a/data/web/js/build/012-api.js +++ b/data/web/js/build/012-api.js @@ -380,4 +380,18 @@ $(document).ready(function() { $('#ConfirmDeleteModal').modal('hide'); }); }); + + // toggle jquery datatables child rows + $('button[data-datatables-expand], a[data-datatables-expand]').on('click', function (e) { + e.preventDefault(); + var tableId = e.target.getAttribute("data-datatables-expand"); + var table = $("#" + tableId).DataTable(); + table.rows(':not(.parent)').nodes().to$().find('td:first-child').trigger('click'); + }); + $('button[data-datatables-collapse], a[data-datatables-collapse]').on('click', function (e) { + e.preventDefault(); + var tableId = e.target.getAttribute("data-datatables-collapse"); + var table = $("#" + tableId).DataTable(); + table.rows('.parent').nodes().to$().find('td:first-child').trigger('click'); + }); }); diff --git a/data/web/js/site/debug.js b/data/web/js/site/debug.js index deb0215e..dcc04210 100644 --- a/data/web/js/site/debug.js +++ b/data/web/js/site/debug.js @@ -47,7 +47,9 @@ $(document).ready(function() { if (mailcow_info.branch === "master"){ check_update(mailcow_info.version_tag, mailcow_info.project_url); } - update_container_stats() + // get public ips + get_public_ips(); + update_container_stats(); }); jQuery(function($){ if (localStorage.getItem("current_page") === null) { @@ -90,6 +92,7 @@ jQuery(function($){ title: lang.time, data: 'time', defaultContent: '', + responsivePriority: 1, render: function(data, type){ var date = new Date(data ? data * 1000 : 0); return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"}); @@ -98,22 +101,27 @@ jQuery(function($){ { title: 'User-Agent', data: 'ua', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-md', + responsivePriority: 5 }, { title: 'Username', data: 'user', - defaultContent: '' + defaultContent: '', + responsivePriority: 4 }, { title: 'IP', data: 'ip', - defaultContent: '' + defaultContent: '', + responsivePriority: 2 }, { title: 'Service', data: 'service', - defaultContent: '' + defaultContent: '', + responsivePriority: 3 } ] }); @@ -155,7 +163,8 @@ jQuery(function($){ { title: lang.message, data: 'message', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-md text-break' } ] }); @@ -240,7 +249,7 @@ jQuery(function($){ title: 'URI', data: 'uri', defaultContent: '', - className: 'text-break min-tablet none' + className: 'dtr-col-md dtr-break-all' }, { title: 'Method', @@ -255,7 +264,8 @@ jQuery(function($){ { title: 'Data', data: 'data', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-md dtr-break-all' } ] }); @@ -394,28 +404,32 @@ jQuery(function($){ { title: 'User', data: 'user', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-sm' }, { title: 'Role', data: 'role', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-sm' }, { title: 'IP', data: 'remote', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-md dtr-break-all' }, { title: lang.message, data: 'msg', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-md dtr-break-all' }, { title: 'Call', data: 'call', defaultContent: '', - className: 'none text-break' + className: 'none dtr-col-md dtr-break-all' } ] }); @@ -453,7 +467,8 @@ jQuery(function($){ { title: 'IP', data: 'real_rip', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-md text-break' }, { title: lang.login_time, @@ -499,7 +514,8 @@ jQuery(function($){ { title: lang.message, data: 'message', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-md dtr-break-all' } ] }); @@ -541,7 +557,8 @@ jQuery(function($){ { title: lang.message, data: 'message', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-md text-break' } ] }); @@ -583,7 +600,8 @@ jQuery(function($){ { title: lang.message, data: 'message', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-md text-break' } ] }); @@ -625,7 +643,8 @@ jQuery(function($){ { title: lang.message, data: 'message', - defaultContent: '' + defaultContent: '', + className: 'dtr-col-md text-break' } ] }); @@ -757,7 +776,8 @@ jQuery(function($){ { title: 'Symbols', data: 'symbols', - defaultContent: '' + defaultContent: '', + className: 'none dtr-col-md' }, { title: 'Msg size', @@ -1200,6 +1220,20 @@ function update_container_stats(timeout=5){ // run again in n seconds setTimeout(update_container_stats, timeout * 1000); } +// get public ips +function get_public_ips(){ + window.fetch("/api/v1/get/status/host/ip", {method:'GET',cache:'no-cache'}).then(function(response) { + return response.json(); + }).then(function(data) { + console.log(data); + + if (data){ + // display host ips + $("#host_ipv4").text(data.ipv4); + $("#host_ipv6").text(data.ipv6); + } + }); +} // format hosts uptime seconds to readable string function formatUptime(seconds){ seconds = Number(seconds); diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index c74494aa..77da5029 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -142,7 +142,9 @@ jQuery(function($){ $(".refresh_table").on('click', function(e) { e.preventDefault(); var table_name = $(this).data('table'); - $('#' + table_name).DataTable().ajax.reload(); + + if ($.fn.DataTable.isDataTable('#' + table_name)) + $('#' + table_name).DataTable().ajax.reload(); }); function draw_domain_table() { // just recalc width if instance already exists @@ -177,9 +179,9 @@ jQuery(function($){ item.chkbox = ''; item.action = '
' + escapeHtml(item.parameters) + '
';
}
item.action = '' + escapeHtml(item.script_data) + '' + item.script_data = '
' + escapeHtml(item.script_data) + '' item.filter_type = '
{{ lang.mailbox.bcc_info|raw }}
- {##} -{{ lang.mailbox.bcc_info|raw }}
+{{ lang.mailbox.recipient_map_info }}
- {##} -{{ lang.mailbox.recipient_map_info }}
+