From 6ff3f3f044b8673d315d0e7dc3f7c33e70bef977 Mon Sep 17 00:00:00 2001 From: realizelol Date: Wed, 25 Jan 2023 23:50:39 +0100 Subject: [PATCH 01/10] [Web] Set pageLength to pagination_size + repect savedState... Fix width in quarantine table. --- data/web/css/site/quarantine.css | 206 +- data/web/js/site/admin.js | 1468 +++++++------- data/web/js/site/debug.js | 144 +- data/web/js/site/edit.js | 442 ++--- data/web/js/site/mailbox.js | 1740 +++++++++-------- data/web/js/site/qhandler.js | 142 +- data/web/js/site/quarantine.js | 583 +++--- data/web/js/site/queue.js | 217 +- data/web/js/site/user.js | 1329 ++++++------- data/web/templates/admin.twig | 6 +- data/web/templates/debug.twig | 40 +- data/web/templates/domainadmin.twig | 2 +- data/web/templates/edit.twig | 2 +- data/web/templates/mailbox.twig | 2 +- data/web/templates/quarantine.twig | 4 +- data/web/templates/queue.twig | 2 +- .../templates/user_domainadmin_common.twig | 2 +- 17 files changed, 3190 insertions(+), 3141 deletions(-) diff --git a/data/web/css/site/quarantine.css b/data/web/css/site/quarantine.css index 98a74d66..0455b7c1 100644 --- a/data/web/css/site/quarantine.css +++ b/data/web/css/site/quarantine.css @@ -1,102 +1,104 @@ -.pagination a { - text-decoration: none !important; -} - -.panel.panel-default { - overflow: visible !important; -} - -.table-responsive { - overflow: visible !important; -} - -.table-responsive { - overflow-x: scroll !important; -} - -.footer-add-item { - display: block; - text-align: center; - font-style: italic; - padding: 10px; - background: #F5F5F5; -} - -@media (min-width: 992px) { - .container { - width: 100%; - } -} -@media (min-width: 1920px) { - .container { - width: 80%; - } -} - -.mass-actions-quarantine { - user-select: none; -} - -.inputMissingAttr { - border-color: #FF4136; -} - -.modal#qidDetailModal p { - word-break: break-all; -} - -span#qid_detail_score { - font-weight: 700; - margin-left: 5px; -} - -span.rspamd-symbol { - display: inline-block; - margin: 2px 6px 2px 0; - border-radius: 4px; - padding: 0 7px; -} - -span.rspamd-symbol.positive { - background: #4CAF50; - border: 1px solid #4CAF50; - color: white; -} - -span.rspamd-symbol.negative { - background: #ff4136; - border: 1px solid #ff4136; - color: white; -} - -span.rspamd-symbol.neutral { - background: #f5f5f5; - color: #333; - border: 1px solid #ccc; -} - -span.rspamd-symbol span.score { - font-weight: 700; -} - -span.mail-address-item { - background-color: #f5f5f5; - border-radius: 4px; - border: 1px solid #ccc; - padding: 2px 7px; - display: inline-block; - margin: 2px 6px 2px 0; -} - -table tbody tr { - cursor: pointer; -} - -table tbody tr td input[type="checkbox"] { - cursor: pointer; -} -.label-rspamd-action { - font-size:110%; - margin:20px; -} - +.pagination a { + text-decoration: none !important; +} + +.panel.panel-default { + overflow: visible !important; +} + +.table-responsive { + overflow: visible !important; +} + +.table-responsive { + overflow-x: scroll !important; +} + +.footer-add-item { + display: block; + text-align: center; + font-style: italic; + padding: 10px; + background: #F5F5F5; +} + +@media (min-width: 992px) { + .container { + width: 100%; + } +} +@media (min-width: 1920px) { + .container { + width: 80%; + } +} + +.mass-actions-quarantine { + user-select: none; +} + +.inputMissingAttr { + border-color: #FF4136; +} + +.modal#qidDetailModal p { + word-break: break-all; +} + +span#qid_detail_score { + font-weight: 700; + margin-left: 5px; +} + +span.rspamd-symbol { + display: inline-block; + margin: 2px 6px 2px 0; + border-radius: 4px; + padding: 0 7px; +} + +span.rspamd-symbol.positive { + background: #4CAF50; + border: 1px solid #4CAF50; + color: white; +} + +span.rspamd-symbol.negative { + background: #ff4136; + border: 1px solid #ff4136; + color: white; +} + +span.rspamd-symbol.neutral { + background: #f5f5f5; + color: #333; + border: 1px solid #ccc; +} + +span.rspamd-symbol span.score { + font-weight: 700; +} + +span.mail-address-item { + background-color: #f5f5f5; + border-radius: 4px; + border: 1px solid #ccc; + padding: 2px 7px; + display: inline-block; + margin: 2px 6px 2px 0; +} + +table tbody tr { + cursor: pointer; +} + +table tbody tr td input[type="checkbox"] { + cursor: pointer; +} +.label-rspamd-action { + font-size:110%; + margin:20px; +} +.senders-mw220 { + max-width: 220px; +} diff --git a/data/web/js/site/admin.js b/data/web/js/site/admin.js index 0dba1aa8..0e5a9ae6 100644 --- a/data/web/js/site/admin.js +++ b/data/web/js/site/admin.js @@ -1,731 +1,737 @@ -// Base64 functions -var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(r){var t,e,o,a,h,n,c,d="",C=0;for(r=Base64._utf8_encode(r);C>2,h=(3&t)<<4|(e=r.charCodeAt(C++))>>4,n=(15&e)<<2|(o=r.charCodeAt(C++))>>6,c=63&o,isNaN(e)?n=c=64:isNaN(o)&&(c=64),d=d+this._keyStr.charAt(a)+this._keyStr.charAt(h)+this._keyStr.charAt(n)+this._keyStr.charAt(c);return d},decode:function(r){var t,e,o,a,h,n,c="",d=0;for(r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");d>4,e=(15&a)<<4|(h=this._keyStr.indexOf(r.charAt(d++)))>>2,o=(3&h)<<6|(n=this._keyStr.indexOf(r.charAt(d++))),c+=String.fromCharCode(t),64!=h&&(c+=String.fromCharCode(e)),64!=n&&(c+=String.fromCharCode(o));return c=Base64._utf8_decode(c)},_utf8_encode:function(r){r=r.replace(/\r\n/g,"\n");for(var t="",e=0;e127&&o<2048?(t+=String.fromCharCode(o>>6|192),t+=String.fromCharCode(63&o|128)):(t+=String.fromCharCode(o>>12|224),t+=String.fromCharCode(o>>6&63|128),t+=String.fromCharCode(63&o|128))}return t},_utf8_decode:function(r){for(var t="",e=0,o=c1=c2=0;e191&&o<224?(c2=r.charCodeAt(e+1),t+=String.fromCharCode((31&o)<<6|63&c2),e+=2):(c2=r.charCodeAt(e+1),c3=r.charCodeAt(e+2),t+=String.fromCharCode((15&o)<<12|(63&c2)<<6|63&c3),e+=3);return t}}; -jQuery(function($){ - // http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery - var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="}; - function jq(myid) {return "#" + myid.replace( /(:|\.|\[|\]|,|=|@)/g, "\\$1" );} - function escapeHtml(n){return String(n).replace(/[&<>"'`=\/]/g,function(n){return entityMap[n]})} - function validateRegex(e){var t=e.split("/"),n=e,r="";t.length>1&&(n=t[1],r=t[2]);try{return new RegExp(n,r),!0}catch(e){return!1}} - function humanFileSize(i){if(Math.abs(i)<1024)return i+" B";var B=["KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],e=-1;do{i/=1024,++e}while(Math.abs(i)>=1024&&e<'col-sm-12 col-md-6'l>>" + - "tr" + - "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", - language: lang_datatables, - ajax: { - type: "GET", - url: "/api/v1/get/domain-admin/all", - dataSrc: function(data){ - return process_table_data(data, 'domainadminstable'); - } - }, - columns: [ - { - // placeholder, so checkbox will not block child row toggle - title: '', - data: null, - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: '', - data: 'chkbox', - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: lang.username, - data: 'username', - defaultContent: '' - }, - { - title: lang.admin_domains, - data: 'selected_domains', - defaultContent: '', - }, - { - title: "TFA", - data: 'tfa_active', - defaultContent: '', - render: function (data, type) { - if(data == 1) return ''; - else return '' - } - }, - { - title: lang.active, - data: 'active', - defaultContent: '', - render: function (data, type) { - if(data == 1) return ''; - else return '' - } - }, - { - title: lang.action, - data: 'action', - className: 'text-md-end dt-sm-head-hidden dt-body-right', - defaultContent: '' - }, - ], - initComplete: function(settings, json){ - } - }); - } - function draw_oauth2_clients() { - // just recalc width if instance already exists - if ($.fn.DataTable.isDataTable('#oauth2clientstable') ) { - $('#oauth2clientstable').DataTable().columns.adjust().responsive.recalc(); - return; - } - - $('#oauth2clientstable').DataTable({ - responsive: true, - processing: true, - serverSide: false, - stateSave: true, - dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + - "tr" + - "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", - language: lang_datatables, - ajax: { - type: "GET", - url: "/api/v1/get/oauth2-client/all", - dataSrc: function(data){ - return process_table_data(data, 'oauth2clientstable'); - } - }, - columns: [ - { - // placeholder, so checkbox will not block child row toggle - title: '', - data: null, - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: '', - data: 'chkbox', - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: 'ID', - data: 'id', - defaultContent: '' - }, - { - title: lang.oauth2_client_id, - data: 'client_id', - defaultContent: '' - }, - { - title: lang.oauth2_client_secret, - data: 'client_secret', - defaultContent: '' - }, - { - title: lang.oauth2_redirect_uri, - data: 'redirect_uri', - defaultContent: '' - }, - { - title: lang.action, - data: 'action', - className: 'text-md-end dt-sm-head-hidden dt-body-right', - defaultContent: '' - }, - ] - }); - } - function draw_admins() { - // just recalc width if instance already exists - if ($.fn.DataTable.isDataTable('#adminstable') ) { - $('#adminstable').DataTable().columns.adjust().responsive.recalc(); - return; - } - - $('#adminstable').DataTable({ - responsive: true, - processing: true, - serverSide: false, - stateSave: true, - dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + - "tr" + - "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", - language: lang_datatables, - ajax: { - type: "GET", - url: "/api/v1/get/admin/all", - dataSrc: function(data){ - return process_table_data(data, 'adminstable'); - } - }, - columns: [ - { - // placeholder, so checkbox will not block child row toggle - title: '', - data: null, - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: '', - data: 'chkbox', - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: lang.username, - data: 'username', - defaultContent: '' - }, - { - title: "TFA", - data: 'tfa_active', - defaultContent: '', - render: function (data, type) { - if(data == 1) return ''; - else return '' - } - }, - { - title: lang.active, - data: 'active', - defaultContent: '', - render: function (data, type) { - if(data == 1) return ''; - else return '' - } - }, - { - title: lang.action, - data: 'action', - defaultContent: '', - className: 'text-md-end dt-sm-head-hidden dt-body-right' - }, - ] - }); - } - function draw_fwd_hosts() { - // just recalc width if instance already exists - if ($.fn.DataTable.isDataTable('#forwardinghoststable') ) { - $('#forwardinghoststable').DataTable().columns.adjust().responsive.recalc(); - return; - } - - $('#forwardinghoststable').DataTable({ - responsive: true, - processing: true, - serverSide: false, - stateSave: true, - dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + - "tr" + - "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", - language: lang_datatables, - ajax: { - type: "GET", - url: "/api/v1/get/fwdhost/all", - dataSrc: function(data){ - return process_table_data(data, 'forwardinghoststable'); - } - }, - columns: [ - { - // placeholder, so checkbox will not block child row toggle - title: '', - data: null, - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: '', - data: 'chkbox', - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: lang.host, - data: 'host', - defaultContent: '' - }, - { - title: lang.source, - data: 'source', - defaultContent: '' - }, - { - title: lang.spamfilter, - data: 'keep_spam', - defaultContent: '', - render: function(data, type){ - return 'yes'==data?'':'no'==data&&''; - } - }, - { - title: lang.action, - data: 'action', - className: 'text-md-end dt-sm-head-hidden dt-body-right', - defaultContent: '' - }, - ] - }); - } - function draw_relayhosts() { - // just recalc width if instance already exists - if ($.fn.DataTable.isDataTable('#relayhoststable') ) { - $('#relayhoststable').DataTable().columns.adjust().responsive.recalc(); - return; - } - - $('#relayhoststable').DataTable({ - responsive: true, - processing: true, - serverSide: false, - stateSave: true, - dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + - "tr" + - "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", - language: lang_datatables, - ajax: { - type: "GET", - url: "/api/v1/get/relayhost/all", - dataSrc: function(data){ - return process_table_data(data, 'relayhoststable'); - } - }, - columns: [ - { - // placeholder, so checkbox will not block child row toggle - title: '', - data: null, - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: '', - data: 'chkbox', - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: 'ID', - data: 'id', - defaultContent: '' - }, - { - title: lang.host, - data: 'hostname', - defaultContent: '' - }, - { - title: lang.username, - data: 'username', - defaultContent: '' - }, - { - title: lang.in_use_by, - data: 'in_use_by', - defaultContent: '' - }, - { - title: lang.active, - data: 'active', - defaultContent: '', - render: function (data, type) { - if(data == 1) return ''; - else return '' - } - }, - { - title: lang.action, - data: 'action', - className: 'text-md-end dt-sm-head-hidden dt-body-right', - defaultContent: '' - }, - ] - }); - } - function draw_transport_maps() { - // just recalc width if instance already exists - if ($.fn.DataTable.isDataTable('#transportstable') ) { - $('#transportstable').DataTable().columns.adjust().responsive.recalc(); - return; - } - - $('#transportstable').DataTable({ - responsive: true, - processing: true, - serverSide: false, - stateSave: true, - dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + - "tr" + - "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", - language: lang_datatables, - ajax: { - type: "GET", - url: "/api/v1/get/transport/all", - dataSrc: function(data){ - return process_table_data(data, 'transportstable'); - } - }, - columns: [ - { - // placeholder, so checkbox will not block child row toggle - title: '', - data: null, - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: '', - data: 'chkbox', - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: 'ID', - data: 'id', - defaultContent: '' - }, - { - title: lang.destination, - data: 'destination', - defaultContent: '' - }, - { - title: lang.nexthop, - data: 'nexthop', - defaultContent: '' - }, - { - title: lang.username, - data: 'username', - defaultContent: '' - }, - { - title: lang.active, - data: 'active', - defaultContent: '', - render: function (data, type) { - if(data == 1) return ''; - else return '' - } - }, - { - title: lang.action, - data: 'action', - className: 'text-md-end dt-sm-head-hidden dt-body-right', - defaultContent: '' - }, - ] - }); - } - - function process_table_data(data, table) { - if (table == 'relayhoststable') { - $.each(data, function (i, item) { - item.action = ''; - if (item.used_by_mailboxes == '') { item.in_use_by = item.used_by_domains; } - else if (item.used_by_domains == '') { item.in_use_by = item.used_by_mailboxes; } - else { item.in_use_by = item.used_by_mailboxes + '
' + item.used_by_domains; } - item.chkbox = ''; - }); - } else if (table == 'transportstable') { - $.each(data, function (i, item) { - if (item.is_mx_based) { - item.destination = ' ' + item.destination + ''; - } - if (item.username) { - item.username = ' ' + item.username; - } - item.action = ''; - item.chkbox = ''; - }); - } else if (table == 'queuetable') { - $.each(data, function (i, item) { - item.chkbox = ''; - rcpts = $.map(item.recipients, function(i) { - return escapeHtml(i); - }); - item.recipients = rcpts.join('
'); - item.action = ''; - }); - } else if (table == 'forwardinghoststable') { - $.each(data, function (i, item) { - item.action = '
' + - ' ' + lang.remove + '' + - '
'; - item.chkbox = ''; - }); - } else if (table == 'oauth2clientstable') { - $.each(data, function (i, item) { - item.action = ''; - item.scope = "profile"; - item.grant_types = 'refresh_token password authorization_code'; - item.chkbox = ''; - }); - } else if (table == 'domainadminstable') { - $.each(data, function (i, item) { - item.selected_domains = escapeHtml(item.selected_domains); - item.selected_domains = item.selected_domains.toString().replace(/,/g, "
"); - item.chkbox = ''; - item.action = ''; - }); - } else if (table == 'adminstable') { - $.each(data, function (i, item) { - if (admin_username.toLowerCase() == item.username.toLowerCase()) { - item.usr = ' ' + item.username; - } else { - item.usr = item.username; - } - item.chkbox = ''; - item.action = ''; - }); - } - return data - }; - - // detect element visibility changes - function onVisible(element, callback) { - $(document).ready(function() { - element_object = document.querySelector(element); - if (element_object === null) return; - - new IntersectionObserver((entries, observer) => { - entries.forEach(entry => { - if(entry.intersectionRatio > 0) { - callback(element_object); - } - }); - }).observe(element_object); - }); - } - // Draw Table if tab is active - onVisible("[id^=adminstable]", () => draw_admins()); - onVisible("[id^=domainadminstable]", () => draw_domain_admins()); - onVisible("[id^=oauth2clientstable]", () => draw_oauth2_clients()); - onVisible("[id^=forwardinghoststable]", () => draw_fwd_hosts()); - onVisible("[id^=relayhoststable]", () => draw_relayhosts()); - onVisible("[id^=transportstable]", () => draw_transport_maps()); - - - $('body').on('click', 'span.footable-toggle', function () { - event.stopPropagation(); - }) - - // API IP check toggle - $("#skip_ip_check_ro").click(function( event ) { - $("#skip_ip_check_ro").not(this).prop('checked', false); - if ($("#skip_ip_check_ro:checked").length > 0) { - $('#allow_from_ro').prop('disabled', true); - } - else { - $("#allow_from_ro").removeAttr('disabled'); - } - }); - $("#skip_ip_check_rw").click(function( event ) { - $("#skip_ip_check_rw").not(this).prop('checked', false); - if ($("#skip_ip_check_rw:checked").length > 0) { - $('#allow_from_rw').prop('disabled', true); - } - else { - $("#allow_from_rw").removeAttr('disabled'); - } - }); - // Relayhost - $('#testRelayhostModal').on('show.bs.modal', function (e) { - $('#test_relayhost_result').text("-"); - button = $(e.relatedTarget) - if (button != null) { - $('#relayhost_id').val(button.data('relayhost-id')); - } - }) - $('#test_relayhost').on('click', function (e) { - e.preventDefault(); - prev = $('#test_relayhost').text(); - $(this).prop("disabled",true); - $(this).html(' '); - $.ajax({ - type: 'GET', - url: 'inc/ajax/relay_check.php', - dataType: 'text', - data: $('#test_relayhost_form').serialize(), - complete: function (data) { - $('#test_relayhost_result').html(data.responseText); - $('#test_relayhost').prop("disabled",false); - $('#test_relayhost').text(prev); - } - }); - }) - // Transport - $('#testTransportModal').on('show.bs.modal', function (e) { - $('#test_transport_result').text("-"); - button = $(e.relatedTarget) - if (button != null) { - $('#transport_id').val(button.data('transport-id')); - $('#transport_type').val(button.data('transport-type')); - } - }) - $('#test_transport').on('click', function (e) { - e.preventDefault(); - prev = $('#test_transport').text(); - $(this).prop("disabled",true); - $(this).html('
Loading...
'); - $.ajax({ - type: 'GET', - url: 'inc/ajax/transport_check.php', - dataType: 'text', - data: $('#test_transport_form').serialize(), - complete: function (data) { - $('#test_transport_result').html(data.responseText); - $('#test_transport').prop("disabled",false); - $('#test_transport').text(prev); - } - }); - }) - // DKIM private key modal - $('#showDKIMprivKey').on('show.bs.modal', function (e) { - $('#priv_key_pre').text("-"); - p_related = $(e.relatedTarget) - if (p_related != null) { - var decoded_key = Base64.decode((p_related.data('priv-key'))); - $('#priv_key_pre').text(decoded_key); - } - }) - // FIDO2 friendly name modal - $('#fido2ChangeFn').on('show.bs.modal', function (e) { - rename_link = $(e.relatedTarget) - if (rename_link != null) { - $('#fido2_cid').val(rename_link.data('cid')); - $('#fido2_subject_desc').text(Base64.decode(rename_link.data('subject'))); - } - }) - // App links - function add_table_row(table_id, type) { - var row = $(''); - if (type == "app_link") { - cols = ''; - cols += ''; - cols += '' + lang.remove_row + ''; - } else if (type == "f2b_regex") { - cols = ''; - cols += ''; - cols += '' + lang.remove_row + ''; - } - row.append(cols); - table_id.append(row); - } - $('#app_link_table').on('click', 'tr a', function (e) { - e.preventDefault(); - $(this).parents('tr').remove(); - }); - $('#f2b_regex_table').on('click', 'tr a', function (e) { - e.preventDefault(); - $(this).parents('tr').remove(); - }); - $('#add_app_link_row').click(function() { - add_table_row($('#app_link_table'), "app_link"); - }); - $('#add_f2b_regex_row').click(function() { - add_table_row($('#f2b_regex_table'), "f2b_regex"); - }); -}); +// Base64 functions +var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(r){var t,e,o,a,h,n,c,d="",C=0;for(r=Base64._utf8_encode(r);C>2,h=(3&t)<<4|(e=r.charCodeAt(C++))>>4,n=(15&e)<<2|(o=r.charCodeAt(C++))>>6,c=63&o,isNaN(e)?n=c=64:isNaN(o)&&(c=64),d=d+this._keyStr.charAt(a)+this._keyStr.charAt(h)+this._keyStr.charAt(n)+this._keyStr.charAt(c);return d},decode:function(r){var t,e,o,a,h,n,c="",d=0;for(r=r.replace(/[^A-Za-z0-9\+\/\=]/g,"");d>4,e=(15&a)<<4|(h=this._keyStr.indexOf(r.charAt(d++)))>>2,o=(3&h)<<6|(n=this._keyStr.indexOf(r.charAt(d++))),c+=String.fromCharCode(t),64!=h&&(c+=String.fromCharCode(e)),64!=n&&(c+=String.fromCharCode(o));return c=Base64._utf8_decode(c)},_utf8_encode:function(r){r=r.replace(/\r\n/g,"\n");for(var t="",e=0;e127&&o<2048?(t+=String.fromCharCode(o>>6|192),t+=String.fromCharCode(63&o|128)):(t+=String.fromCharCode(o>>12|224),t+=String.fromCharCode(o>>6&63|128),t+=String.fromCharCode(63&o|128))}return t},_utf8_decode:function(r){for(var t="",e=0,o=c1=c2=0;e191&&o<224?(c2=r.charCodeAt(e+1),t+=String.fromCharCode((31&o)<<6|63&c2),e+=2):(c2=r.charCodeAt(e+1),c3=r.charCodeAt(e+2),t+=String.fromCharCode((15&o)<<12|(63&c2)<<6|63&c3),e+=3);return t}}; +jQuery(function($){ + // http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery + var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="}; + function jq(myid) {return "#" + myid.replace( /(:|\.|\[|\]|,|=|@)/g, "\\$1" );} + function escapeHtml(n){return String(n).replace(/[&<>"'`=\/]/g,function(n){return entityMap[n]})} + function validateRegex(e){var t=e.split("/"),n=e,r="";t.length>1&&(n=t[1],r=t[2]);try{return new RegExp(n,r),!0}catch(e){return!1}} + function humanFileSize(i){if(Math.abs(i)<1024)return i+" B";var B=["KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"],e=-1;do{i/=1024,++e}while(Math.abs(i)>=1024&&e<'col-sm-12 col-md-6'l>>" + + "tr" + + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", + language: lang_datatables, + ajax: { + type: "GET", + url: "/api/v1/get/domain-admin/all", + dataSrc: function(data){ + return process_table_data(data, 'domainadminstable'); + } + }, + columns: [ + { + // placeholder, so checkbox will not block child row toggle + title: '', + data: null, + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: '', + data: 'chkbox', + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: lang.username, + data: 'username', + defaultContent: '' + }, + { + title: lang.admin_domains, + data: 'selected_domains', + defaultContent: '', + }, + { + title: "TFA", + data: 'tfa_active', + defaultContent: '', + render: function (data, type) { + if(data == 1) return ''; + else return ''; + } + }, + { + title: lang.active, + data: 'active', + defaultContent: '', + render: function (data, type) { + if(data == 1) return ''; + else return ''; + } + }, + { + title: lang.action, + data: 'action', + className: 'text-md-end dt-sm-head-hidden dt-body-right', + defaultContent: '' + }, + ], + initComplete: function(settings, json){ + } + }); + } + function draw_oauth2_clients() { + // just recalc width if instance already exists + if ($.fn.DataTable.isDataTable('#oauth2clientstable') ) { + $('#oauth2clientstable').DataTable().columns.adjust().responsive.recalc(); + return; + } + + $('#oauth2clientstable').DataTable({ + responsive: true, + processing: true, + serverSide: false, + stateSave: true, + pageLength: pagination_size, + dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + + "tr" + + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", + language: lang_datatables, + ajax: { + type: "GET", + url: "/api/v1/get/oauth2-client/all", + dataSrc: function(data){ + return process_table_data(data, 'oauth2clientstable'); + } + }, + columns: [ + { + // placeholder, so checkbox will not block child row toggle + title: '', + data: null, + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: '', + data: 'chkbox', + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: 'ID', + data: 'id', + defaultContent: '' + }, + { + title: lang.oauth2_client_id, + data: 'client_id', + defaultContent: '' + }, + { + title: lang.oauth2_client_secret, + data: 'client_secret', + defaultContent: '' + }, + { + title: lang.oauth2_redirect_uri, + data: 'redirect_uri', + defaultContent: '' + }, + { + title: lang.action, + data: 'action', + className: 'text-md-end dt-sm-head-hidden dt-body-right', + defaultContent: '' + }, + ] + }); + } + function draw_admins() { + // just recalc width if instance already exists + if ($.fn.DataTable.isDataTable('#adminstable') ) { + $('#adminstable').DataTable().columns.adjust().responsive.recalc(); + return; + } + + $('#adminstable').DataTable({ + responsive: true, + processing: true, + serverSide: false, + stateSave: true, + pageLength: pagination_size, + dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + + "tr" + + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", + language: lang_datatables, + ajax: { + type: "GET", + url: "/api/v1/get/admin/all", + dataSrc: function(data){ + return process_table_data(data, 'adminstable'); + } + }, + columns: [ + { + // placeholder, so checkbox will not block child row toggle + title: '', + data: null, + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: '', + data: 'chkbox', + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: lang.username, + data: 'username', + defaultContent: '' + }, + { + title: "TFA", + data: 'tfa_active', + defaultContent: '', + render: function (data, type) { + if(data == 1) return ''; + else return ''; + } + }, + { + title: lang.active, + data: 'active', + defaultContent: '', + render: function (data, type) { + if(data == 1) return ''; + else return ''; + } + }, + { + title: lang.action, + data: 'action', + defaultContent: '', + className: 'text-md-end dt-sm-head-hidden dt-body-right' + }, + ] + }); + } + function draw_fwd_hosts() { + // just recalc width if instance already exists + if ($.fn.DataTable.isDataTable('#forwardinghoststable') ) { + $('#forwardinghoststable').DataTable().columns.adjust().responsive.recalc(); + return; + } + + $('#forwardinghoststable').DataTable({ + responsive: true, + processing: true, + serverSide: false, + stateSave: true, + pageLength: pagination_size, + dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + + "tr" + + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", + language: lang_datatables, + ajax: { + type: "GET", + url: "/api/v1/get/fwdhost/all", + dataSrc: function(data){ + return process_table_data(data, 'forwardinghoststable'); + } + }, + columns: [ + { + // placeholder, so checkbox will not block child row toggle + title: '', + data: null, + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: '', + data: 'chkbox', + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: lang.host, + data: 'host', + defaultContent: '' + }, + { + title: lang.source, + data: 'source', + defaultContent: '' + }, + { + title: lang.spamfilter, + data: 'keep_spam', + defaultContent: '', + render: function(data, type){ + return 'yes'==data?'':'no'==data&&''; + } + }, + { + title: lang.action, + data: 'action', + className: 'text-md-end dt-sm-head-hidden dt-body-right', + defaultContent: '' + }, + ] + }); + } + function draw_relayhosts() { + // just recalc width if instance already exists + if ($.fn.DataTable.isDataTable('#relayhoststable') ) { + $('#relayhoststable').DataTable().columns.adjust().responsive.recalc(); + return; + } + + $('#relayhoststable').DataTable({ + responsive: true, + processing: true, + serverSide: false, + stateSave: true, + pageLength: pagination_size, + dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + + "tr" + + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", + language: lang_datatables, + ajax: { + type: "GET", + url: "/api/v1/get/relayhost/all", + dataSrc: function(data){ + return process_table_data(data, 'relayhoststable'); + } + }, + columns: [ + { + // placeholder, so checkbox will not block child row toggle + title: '', + data: null, + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: '', + data: 'chkbox', + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: 'ID', + data: 'id', + defaultContent: '' + }, + { + title: lang.host, + data: 'hostname', + defaultContent: '' + }, + { + title: lang.username, + data: 'username', + defaultContent: '' + }, + { + title: lang.in_use_by, + data: 'in_use_by', + defaultContent: '' + }, + { + title: lang.active, + data: 'active', + defaultContent: '', + render: function (data, type) { + if(data == 1) return ''; + else return ''; + } + }, + { + title: lang.action, + data: 'action', + className: 'text-md-end dt-sm-head-hidden dt-body-right', + defaultContent: '' + }, + ] + }); + } + function draw_transport_maps() { + // just recalc width if instance already exists + if ($.fn.DataTable.isDataTable('#transportstable') ) { + $('#transportstable').DataTable().columns.adjust().responsive.recalc(); + return; + } + + $('#transportstable').DataTable({ + responsive: true, + processing: true, + serverSide: false, + stateSave: true, + pageLength: pagination_size, + dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + + "tr" + + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", + language: lang_datatables, + ajax: { + type: "GET", + url: "/api/v1/get/transport/all", + dataSrc: function(data){ + return process_table_data(data, 'transportstable'); + } + }, + columns: [ + { + // placeholder, so checkbox will not block child row toggle + title: '', + data: null, + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: '', + data: 'chkbox', + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: 'ID', + data: 'id', + defaultContent: '' + }, + { + title: lang.destination, + data: 'destination', + defaultContent: '' + }, + { + title: lang.nexthop, + data: 'nexthop', + defaultContent: '' + }, + { + title: lang.username, + data: 'username', + defaultContent: '' + }, + { + title: lang.active, + data: 'active', + defaultContent: '', + render: function (data, type) { + if(data == 1) return ''; + else return ''; + } + }, + { + title: lang.action, + data: 'action', + className: 'text-md-end dt-sm-head-hidden dt-body-right', + defaultContent: '' + }, + ] + }); + } + + function process_table_data(data, table) { + if (table == 'relayhoststable') { + $.each(data, function (i, item) { + item.action = ''; + if (item.used_by_mailboxes == '') { item.in_use_by = item.used_by_domains; } + else if (item.used_by_domains == '') { item.in_use_by = item.used_by_mailboxes; } + else { item.in_use_by = item.used_by_mailboxes + '
' + item.used_by_domains; } + item.chkbox = ''; + }); + } else if (table == 'transportstable') { + $.each(data, function (i, item) { + if (item.is_mx_based) { + item.destination = ' ' + item.destination + ''; + } + if (item.username) { + item.username = ' ' + item.username; + } + item.action = ''; + item.chkbox = ''; + }); + } else if (table == 'queuetable') { + $.each(data, function (i, item) { + item.chkbox = ''; + rcpts = $.map(item.recipients, function(i) { + return escapeHtml(i); + }); + item.recipients = rcpts.join('
'); + item.action = ''; + }); + } else if (table == 'forwardinghoststable') { + $.each(data, function (i, item) { + item.action = '
' + + ' ' + lang.remove + '' + + '
'; + item.chkbox = ''; + }); + } else if (table == 'oauth2clientstable') { + $.each(data, function (i, item) { + item.action = ''; + item.scope = "profile"; + item.grant_types = 'refresh_token password authorization_code'; + item.chkbox = ''; + }); + } else if (table == 'domainadminstable') { + $.each(data, function (i, item) { + item.selected_domains = escapeHtml(item.selected_domains); + item.selected_domains = item.selected_domains.toString().replace(/,/g, "
"); + item.chkbox = ''; + item.action = ''; + }); + } else if (table == 'adminstable') { + $.each(data, function (i, item) { + if (admin_username.toLowerCase() == item.username.toLowerCase()) { + item.usr = ' ' + item.username; + } else { + item.usr = item.username; + } + item.chkbox = ''; + item.action = ''; + }); + } + return data + }; + + // detect element visibility changes + function onVisible(element, callback) { + $(document).ready(function() { + element_object = document.querySelector(element); + if (element_object === null) return; + + new IntersectionObserver((entries, observer) => { + entries.forEach(entry => { + if(entry.intersectionRatio > 0) { + callback(element_object); + } + }); + }).observe(element_object); + }); + } + // Draw Table if tab is active + onVisible("[id^=adminstable]", () => draw_admins()); + onVisible("[id^=domainadminstable]", () => draw_domain_admins()); + onVisible("[id^=oauth2clientstable]", () => draw_oauth2_clients()); + onVisible("[id^=forwardinghoststable]", () => draw_fwd_hosts()); + onVisible("[id^=relayhoststable]", () => draw_relayhosts()); + onVisible("[id^=transportstable]", () => draw_transport_maps()); + + + $('body').on('click', 'span.footable-toggle', function () { + event.stopPropagation(); + }) + + // API IP check toggle + $("#skip_ip_check_ro").click(function( event ) { + $("#skip_ip_check_ro").not(this).prop('checked', false); + if ($("#skip_ip_check_ro:checked").length > 0) { + $('#allow_from_ro').prop('disabled', true); + } + else { + $("#allow_from_ro").removeAttr('disabled'); + } + }); + $("#skip_ip_check_rw").click(function( event ) { + $("#skip_ip_check_rw").not(this).prop('checked', false); + if ($("#skip_ip_check_rw:checked").length > 0) { + $('#allow_from_rw').prop('disabled', true); + } + else { + $("#allow_from_rw").removeAttr('disabled'); + } + }); + // Relayhost + $('#testRelayhostModal').on('show.bs.modal', function (e) { + $('#test_relayhost_result').text("-"); + button = $(e.relatedTarget) + if (button != null) { + $('#relayhost_id').val(button.data('relayhost-id')); + } + }) + $('#test_relayhost').on('click', function (e) { + e.preventDefault(); + prev = $('#test_relayhost').text(); + $(this).prop("disabled",true); + $(this).html(' '); + $.ajax({ + type: 'GET', + url: 'inc/ajax/relay_check.php', + dataType: 'text', + data: $('#test_relayhost_form').serialize(), + complete: function (data) { + $('#test_relayhost_result').html(data.responseText); + $('#test_relayhost').prop("disabled",false); + $('#test_relayhost').text(prev); + } + }); + }) + // Transport + $('#testTransportModal').on('show.bs.modal', function (e) { + $('#test_transport_result').text("-"); + button = $(e.relatedTarget) + if (button != null) { + $('#transport_id').val(button.data('transport-id')); + $('#transport_type').val(button.data('transport-type')); + } + }) + $('#test_transport').on('click', function (e) { + e.preventDefault(); + prev = $('#test_transport').text(); + $(this).prop("disabled",true); + $(this).html('
Loading...
'); + $.ajax({ + type: 'GET', + url: 'inc/ajax/transport_check.php', + dataType: 'text', + data: $('#test_transport_form').serialize(), + complete: function (data) { + $('#test_transport_result').html(data.responseText); + $('#test_transport').prop("disabled",false); + $('#test_transport').text(prev); + } + }); + }) + // DKIM private key modal + $('#showDKIMprivKey').on('show.bs.modal', function (e) { + $('#priv_key_pre').text("-"); + p_related = $(e.relatedTarget) + if (p_related != null) { + var decoded_key = Base64.decode((p_related.data('priv-key'))); + $('#priv_key_pre').text(decoded_key); + } + }) + // FIDO2 friendly name modal + $('#fido2ChangeFn').on('show.bs.modal', function (e) { + rename_link = $(e.relatedTarget) + if (rename_link != null) { + $('#fido2_cid').val(rename_link.data('cid')); + $('#fido2_subject_desc').text(Base64.decode(rename_link.data('subject'))); + } + }) + // App links + function add_table_row(table_id, type) { + var row = $(''); + if (type == "app_link") { + cols = ''; + cols += ''; + cols += '' + lang.remove_row + ''; + } else if (type == "f2b_regex") { + cols = ''; + cols += ''; + cols += '' + lang.remove_row + ''; + } + row.append(cols); + table_id.append(row); + } + $('#app_link_table').on('click', 'tr a', function (e) { + e.preventDefault(); + $(this).parents('tr').remove(); + }); + $('#f2b_regex_table').on('click', 'tr a', function (e) { + e.preventDefault(); + $(this).parents('tr').remove(); + }); + $('#add_app_link_row').click(function() { + add_table_row($('#app_link_table'), "app_link"); + }); + $('#add_f2b_regex_row').click(function() { + add_table_row($('#f2b_regex_table'), "f2b_regex"); + }); +}); diff --git a/data/web/js/site/debug.js b/data/web/js/site/debug.js index a7b06e5a..e0b9a5ab 100644 --- a/data/web/js/site/debug.js +++ b/data/web/js/site/debug.js @@ -34,7 +34,7 @@ $(document).ready(function() { }); // set update loop container list - containersToUpdate = {} + containersToUpdate = {}; // set default ChartJs Font Color Chart.defaults.color = '#999'; // create host cpu and mem charts @@ -44,14 +44,13 @@ $(document).ready(function() { check_update(mailcow_info.version_tag, mailcow_info.project_url); } $("#maiclow_version").click(function(){ - if (mailcow_cc_role !== "admin" && mailcow_cc_role !== "domainadmin" || - mailcow_info.branch !== "master") + if (mailcow_cc_role !== "admin" && mailcow_cc_role !== "domainadmin" || mailcow_info.branch !== "master") return; showVersionModal("Version " + mailcow_info.version_tag, mailcow_info.version_tag); }) // get public ips - $("#host_show_ip").click(function(){ + $("#host_show_ip").click(function(){ $("#host_show_ip").find(".text").addClass("d-none"); $("#host_show_ip").find(".spinner-border").removeClass("d-none"); @@ -76,7 +75,7 @@ $(document).ready(function() { $("#host_ipv6").addClass("d-block"); }).catch(function(error){ console.log(error); - + $("#host_ipv6").removeClass("d-none"); $("#host_ipv6").addClass("d-block"); $("#host_ipv6").addClass("text-danger"); @@ -119,10 +118,11 @@ jQuery(function($){ } var table = $('#autodiscover_log').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -188,10 +188,11 @@ jQuery(function($){ } var table = $('#postfix_log').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -242,10 +243,11 @@ jQuery(function($){ } var table = $('#watchdog_log').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -300,10 +302,11 @@ jQuery(function($){ } var table = $('#api_log').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -352,7 +355,7 @@ jQuery(function($){ } ] }); - + table.on('responsive-resize', function (e, datatable, columns){ hideTableExpandCollapseBtn('#tab-api-logs', '#api_log'); }); @@ -365,10 +368,11 @@ jQuery(function($){ } var table = $('#rl_log').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -455,7 +459,7 @@ jQuery(function($){ } ] }); - + table.on('responsive-resize', function (e, datatable, columns){ hideTableExpandCollapseBtn('#tab-rl-logs', '#rl_log'); }); @@ -468,10 +472,11 @@ jQuery(function($){ } var table = $('#ui_logs').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -538,7 +543,7 @@ jQuery(function($){ } ] }); - + table.on('responsive-resize', function (e, datatable, columns){ hideTableExpandCollapseBtn('#tab-ui-logs', '#ui_log'); }); @@ -551,10 +556,11 @@ jQuery(function($){ } var table = $('#sasl_logs').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -598,7 +604,7 @@ jQuery(function($){ } ] }); - + table.on('responsive-resize', function (e, datatable, columns){ hideTableExpandCollapseBtn('#tab-sasl-logs', '#sasl_logs'); }); @@ -611,10 +617,11 @@ jQuery(function($){ } var table = $('#acme_log').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -647,7 +654,7 @@ jQuery(function($){ } ] }); - + table.on('responsive-resize', function (e, datatable, columns){ hideTableExpandCollapseBtn('#tab-acme-logs', '#acme_log'); }); @@ -660,10 +667,11 @@ jQuery(function($){ } var table = $('#netfilter_log').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -701,7 +709,7 @@ jQuery(function($){ } ] }); - + table.on('responsive-resize', function (e, datatable, columns){ hideTableExpandCollapseBtn('#tab-netfilter-logs', '#netfilter_log'); }); @@ -714,10 +722,11 @@ jQuery(function($){ } var table = $('#sogo_log').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -755,7 +764,7 @@ jQuery(function($){ } ] }); - + table.on('responsive-resize', function (e, datatable, columns){ hideTableExpandCollapseBtn('#tab-sogo-logs', '#sogo_log'); }); @@ -768,10 +777,11 @@ jQuery(function($){ } var table = $('#dovecot_log').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -883,10 +893,11 @@ jQuery(function($){ } var table = $('#rspamd_history').DataTable({ - responsive: true, + responsive: true, processing: true, serverSide: false, stateSave: true, + pageLength: log_pagination_size, dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + "tr" + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", @@ -983,7 +994,7 @@ jQuery(function($){ } ] }); - + table.on('responsive-resize', function (e, datatable, columns){ hideTableExpandCollapseBtn('#tab-rspamd-history', '#rspamd_history'); }); @@ -998,31 +1009,31 @@ jQuery(function($){ item.rcpt = escapeHtml(item.rcpt_smtp.join(", ")); } item.symbols = Object.keys(item.symbols).sort(function (a, b) { - if (item.symbols[a].score === 0) return 1 - if (item.symbols[b].score === 0) return -1 + if (item.symbols[a].score === 0) return 1; + if (item.symbols[b].score === 0) return -1; if (item.symbols[b].score < 0 && item.symbols[a].score < 0) { - return item.symbols[a].score - item.symbols[b].score + return item.symbols[a].score - item.symbols[b].score; } if (item.symbols[b].score > 0 && item.symbols[a].score > 0) { - return item.symbols[b].score - item.symbols[a].score + return item.symbols[b].score - item.symbols[a].score; } - return item.symbols[b].score - item.symbols[a].score + return item.symbols[b].score - item.symbols[a].score; }).map(function(key) { var sym = item.symbols[key]; if (sym.score < 0) { - sym.score_formatted = '(' + sym.score + ')' + sym.score_formatted = '(' + sym.score + ')'; } else if (sym.score === 0) { - sym.score_formatted = '(' + sym.score + ')' + sym.score_formatted = '(' + sym.score + ')'; } else { - sym.score_formatted = '(' + sym.score + ')' + sym.score_formatted = '(' + sym.score + ')'; } var str = '' + key + ' ' + sym.score_formatted; if (sym.options) { str += ' [' + escapeHtml(sym.options.join(", ")) + "]"; } - return str + return str; }).join('
\n'); item.subject = escapeHtml(item.subject); var scan_time = item.time_real.toFixed(3); @@ -1155,14 +1166,14 @@ jQuery(function($){ } }); } - return data + return data; }; $('.add_log_lines').on('click', function (e) { e.preventDefault(); - var log_table= $(this).data("table") - var new_nrows = $(this).data("nrows") - var post_process = $(this).data("post-process") - var log_url = $(this).data("log-url") + var log_table= $(this).data("table"); + var new_nrows = $(this).data("nrows"); + var post_process = $(this).data("post-process"); + var log_url = $(this).data("log-url"); if (log_table === undefined || new_nrows === undefined || post_process === undefined || log_url === undefined) { console.log("no data-table or data-nrows or log_url or data-post-process attr found"); return; @@ -1184,9 +1195,9 @@ jQuery(function($){ }) function hideTableExpandCollapseBtn(tab, table){ if ($(table).hasClass('collapsed')) - $(tab).find(".table_collapse_option").show(); + $(tab).find(".table_collapse_option").show(); else - $(tab).find(".table_collapse_option").hide(); + $(tab).find(".table_collapse_option").hide(); } // detect element visibility changes @@ -1220,7 +1231,6 @@ jQuery(function($){ onVisible("[id^=rspamd_donut]", () => rspamd_pie_graph()); - // start polling host stats if tab is active onVisible("[id^=tab-containers]", () => update_stats()); // start polling container stats if collapse is active @@ -1303,9 +1313,9 @@ function update_stats(timeout=5){ if (mem_chart.data.labels.length > 30) mem_chart.data.labels.shift(); cpu_chart.data.datasets[0].data.push(data.cpu.usage); - if (cpu_chart.data.datasets[0].data.length > 30) cpu_chart.data.datasets[0].data.shift(); + if (cpu_chart.data.datasets[0].data.length > 30) cpu_chart.data.datasets[0].data.shift(); mem_chart.data.datasets[0].data.push(data.memory.usage); - if (mem_chart.data.datasets[0].data.length > 30) mem_chart.data.datasets[0].data.shift(); + if (mem_chart.data.datasets[0].data.length > 30) mem_chart.data.datasets[0].data.shift(); cpu_chart.update(); mem_chart.update(); @@ -1464,23 +1474,23 @@ function createReadWriteChart(chart_id, read_lable, write_lable){ }; var optionsNet = { interaction: { - mode: 'index' + mode: 'index' }, scales: { yAxis: { min: 0, grid: { - display: false + display: false }, ticks: { callback: function(i, index, ticks) { - return formatBytes(i); + return formatBytes(i); } } }, xAxis: { grid: { - display: false + display: false } } } @@ -1528,13 +1538,13 @@ function createHostCpuAndMemChart(){ }; var optionsCpu = { interaction: { - mode: 'index' + mode: 'index' }, scales: { yAxis: { min: 0, grid: { - display: false + display: false }, ticks: { callback: function(i, index, ticks) { @@ -1544,7 +1554,7 @@ function createHostCpuAndMemChart(){ }, xAxis: { grid: { - display: false + display: false } } } @@ -1566,13 +1576,13 @@ function createHostCpuAndMemChart(){ }; var optionsMem = { interaction: { - mode: 'index' + mode: 'index' }, scales: { yAxis: { min: 0, grid: { - display: false + display: false }, ticks: { callback: function(i, index, ticks) { @@ -1582,7 +1592,7 @@ function createHostCpuAndMemChart(){ }, xAxis: { grid: { - display: false + display: false } } } @@ -1678,22 +1688,22 @@ function parseGithubMarkdownLinks(inputText) { replacePattern1 = /(\b(https?):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim; replacedText = inputText.replace(replacePattern1, (matched, index, original, input_string) => { - if (matched.includes('github.com')){ - // return short link if it's github link - last_uri_path = matched.split('/'); - last_uri_path = last_uri_path[last_uri_path.length - 1]; + if (matched.includes('github.com')){ + // return short link if it's github link + last_uri_path = matched.split('/'); + last_uri_path = last_uri_path[last_uri_path.length - 1]; - // adjust Full Changelog link to match last git version and new git version, if link is a compare link - if (matched.includes('/compare/') && mailcow_info.last_version_tag !== ''){ - matched = matched.replace(last_uri_path, mailcow_info.last_version_tag + '...' + mailcow_info.version_tag); - last_uri_path = mailcow_info.last_version_tag + '...' + mailcow_info.version_tag; - } + // adjust Full Changelog link to match last git version and new git version, if link is a compare link + if (matched.includes('/compare/') && mailcow_info.last_version_tag !== ''){ + matched = matched.replace(last_uri_path, mailcow_info.last_version_tag + '...' + mailcow_info.version_tag); + last_uri_path = mailcow_info.last_version_tag + '...' + mailcow_info.version_tag; + } - return '' + last_uri_path + '
'; - }; + return '' + last_uri_path + '
'; + }; - // if it's not a github link, return complete link - return '' + matched + ''; + // if it's not a github link, return complete link + return '' + matched + ''; }); return replacedText; diff --git a/data/web/js/site/edit.js b/data/web/js/site/edit.js index 4c57b35e..4680bdfa 100644 --- a/data/web/js/site/edit.js +++ b/data/web/js/site/edit.js @@ -1,220 +1,222 @@ -$(document).ready(function() { - $(".arrow-toggle").on('click', function(e) { e.preventDefault(); $(this).find('.arrow').toggleClass("animation"); }); - $("#pushover_delete").click(function() { return confirm(lang.delete_ays); }); - $(".goto_checkbox").click(function( event ) { - $("form[data-id='editalias'] .goto_checkbox").not(this).prop('checked', false); - if ($("form[data-id='editalias'] .goto_checkbox:checked").length > 0) { - $('#textarea_alias_goto').prop('disabled', true); - } - else { - $("#textarea_alias_goto").removeAttr('disabled'); - } - }); - $("#disable_sender_check").click(function( event ) { - if ($("form[data-id='editmailbox'] #disable_sender_check:checked").length > 0) { - $('#editSelectSenderACL').prop('disabled', true); - $('#editSelectSenderACL').selectpicker('refresh'); - } - else { - $('#editSelectSenderACL').prop('disabled', false); - $('#editSelectSenderACL').selectpicker('refresh'); - } - }); - if ($("form[data-id='editalias'] .goto_checkbox:checked").length > 0) { - $('#textarea_alias_goto').prop('disabled', true); - } - - $("#mailbox-password-warning-close").click(function( event ) { - $('#mailbox-passwd-hidden-info').addClass('hidden'); - $('#mailbox-passwd-form-groups').removeClass('hidden'); - }); - // Sender ACL - if ($("#editSelectSenderACL option[value='\*']:selected").length > 0){ - $("#sender_acl_disabled").show(); - } - $('#editSelectSenderACL').change(function() { - if ($("#editSelectSenderACL option[value='\*']:selected").length > 0){ - $("#sender_acl_disabled").show(); - } - else { - $("#sender_acl_disabled").hide(); - } - }); - // Resources - if ($("#editSelectMultipleBookings").val() == "custom") { - $("#multiple_bookings_custom_div").show(); - $('input[name=multiple_bookings]').val($("#multiple_bookings_custom").val()); - } - $("#editSelectMultipleBookings").change(function() { - $('input[name=multiple_bookings]').val($("#editSelectMultipleBookings").val()); - if ($('input[name=multiple_bookings]').val() == "custom") { - $("#multiple_bookings_custom_div").show(); - } - else { - $("#multiple_bookings_custom_div").hide(); - } - }); - $("#multiple_bookings_custom").bind("change keypress keyup blur", function() { - $('input[name=multiple_bookings]').val($("#multiple_bookings_custom").val()); - }); - - // load tags - if ($('#tags').length){ - var tagsEl = $('#tags').parent().find('.tag-values')[0]; - console.log($(tagsEl).val()) - var tags = JSON.parse($(tagsEl).val()); - $(tagsEl).val(""); - - for (var i = 0; i < tags.length; i++) - addTag($('#tags'), tags[i]); - } -}); - -jQuery(function($){ - // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript - function validateEmail(email) { - var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; - return re.test(email); - } - function draw_wl_policy_domain_table() { - $('#wl_policy_domain_table').DataTable({ - responsive: true, - processing: true, - serverSide: false, - stateSave: true, - dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + - "tr" + - "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", - language: lang_datatables, - ajax: { - type: "GET", - url: '/api/v1/get/policy_wl_domain/' + table_for_domain, - dataSrc: function(data){ - $.each(data, function (i, item) { - if (!validateEmail(item.object)) { - item.chkbox = ''; - } - else { - item.chkbox = ''; - } - }); - - return data; - } - }, - columns: [ - { - // placeholder, so checkbox will not block child row toggle - title: '', - data: null, - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: '', - data: 'chkbox', - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: 'ID', - data: 'prefid', - defaultContent: '' - }, - { - title: lang_user.spamfilter_table_rule, - data: 'value', - defaultContent: '' - }, - { - title: 'Scope', - data: 'object', - defaultContent: '' - } - ] - }); - } - function draw_bl_policy_domain_table() { - $('#bl_policy_domain_table').DataTable({ - responsive: true, - processing: true, - serverSide: false, - stateSave: true, - dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + - "tr" + - "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", - language: lang_datatables, - ajax: { - type: "GET", - url: '/api/v1/get/policy_bl_domain/' + table_for_domain, - dataSrc: function(data){ - $.each(data, function (i, item) { - if (!validateEmail(item.object)) { - item.chkbox = ''; - } - else { - item.chkbox = ''; - } - }); - - return data; - } - }, - columns: [ - { - // placeholder, so checkbox will not block child row toggle - title: '', - data: null, - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: '', - data: 'chkbox', - searchable: false, - orderable: false, - defaultContent: '' - }, - { - title: 'ID', - data: 'prefid', - defaultContent: '' - }, - { - title: lang_user.spamfilter_table_rule, - data: 'value', - defaultContent: '' - }, - { - title: 'Scope', - data: 'object', - defaultContent: '' - } - ] - }); - } - - - // detect element visibility changes - function onVisible(element, callback) { - $(document).ready(function() { - element_object = document.querySelector(element); - if (element_object === null) return; - - new IntersectionObserver((entries, observer) => { - entries.forEach(entry => { - if(entry.intersectionRatio > 0) { - callback(element_object); - observer.disconnect(); - } - }); - }).observe(element_object); - }); - } - // Draw Table if tab is active - onVisible("[id^=wl_policy_domain_table]", () => draw_wl_policy_domain_table()); - onVisible("[id^=bl_policy_domain_table]", () => draw_bl_policy_domain_table()); -}); +$(document).ready(function() { + $(".arrow-toggle").on('click', function(e) { e.preventDefault(); $(this).find('.arrow').toggleClass("animation"); }); + $("#pushover_delete").click(function() { return confirm(lang.delete_ays); }); + $(".goto_checkbox").click(function( event ) { + $("form[data-id='editalias'] .goto_checkbox").not(this).prop('checked', false); + if ($("form[data-id='editalias'] .goto_checkbox:checked").length > 0) { + $('#textarea_alias_goto').prop('disabled', true); + } + else { + $("#textarea_alias_goto").removeAttr('disabled'); + } + }); + $("#disable_sender_check").click(function( event ) { + if ($("form[data-id='editmailbox'] #disable_sender_check:checked").length > 0) { + $('#editSelectSenderACL').prop('disabled', true); + $('#editSelectSenderACL').selectpicker('refresh'); + } + else { + $('#editSelectSenderACL').prop('disabled', false); + $('#editSelectSenderACL').selectpicker('refresh'); + } + }); + if ($("form[data-id='editalias'] .goto_checkbox:checked").length > 0) { + $('#textarea_alias_goto').prop('disabled', true); + } + + $("#mailbox-password-warning-close").click(function( event ) { + $('#mailbox-passwd-hidden-info').addClass('hidden'); + $('#mailbox-passwd-form-groups').removeClass('hidden'); + }); + // Sender ACL + if ($("#editSelectSenderACL option[value='\*']:selected").length > 0){ + $("#sender_acl_disabled").show(); + } + $('#editSelectSenderACL').change(function() { + if ($("#editSelectSenderACL option[value='\*']:selected").length > 0){ + $("#sender_acl_disabled").show(); + } + else { + $("#sender_acl_disabled").hide(); + } + }); + // Resources + if ($("#editSelectMultipleBookings").val() == "custom") { + $("#multiple_bookings_custom_div").show(); + $('input[name=multiple_bookings]').val($("#multiple_bookings_custom").val()); + } + $("#editSelectMultipleBookings").change(function() { + $('input[name=multiple_bookings]').val($("#editSelectMultipleBookings").val()); + if ($('input[name=multiple_bookings]').val() == "custom") { + $("#multiple_bookings_custom_div").show(); + } + else { + $("#multiple_bookings_custom_div").hide(); + } + }); + $("#multiple_bookings_custom").bind("change keypress keyup blur", function() { + $('input[name=multiple_bookings]').val($("#multiple_bookings_custom").val()); + }); + + // load tags + if ($('#tags').length){ + var tagsEl = $('#tags').parent().find('.tag-values')[0]; + console.log($(tagsEl).val()) + var tags = JSON.parse($(tagsEl).val()); + $(tagsEl).val(""); + + for (var i = 0; i < tags.length; i++) + addTag($('#tags'), tags[i]); + } +}); + +jQuery(function($){ + // http://stackoverflow.com/questions/46155/validate-email-address-in-javascript + function validateEmail(email) { + var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; + return re.test(email); + } + function draw_wl_policy_domain_table() { + $('#wl_policy_domain_table').DataTable({ + responsive: true, + processing: true, + serverSide: false, + stateSave: true, + pageLength: pagination_size, + dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + + "tr" + + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", + language: lang_datatables, + ajax: { + type: "GET", + url: '/api/v1/get/policy_wl_domain/' + table_for_domain, + dataSrc: function(data){ + $.each(data, function (i, item) { + if (!validateEmail(item.object)) { + item.chkbox = ''; + } + else { + item.chkbox = ''; + } + }); + + return data; + } + }, + columns: [ + { + // placeholder, so checkbox will not block child row toggle + title: '', + data: null, + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: '', + data: 'chkbox', + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: 'ID', + data: 'prefid', + defaultContent: '' + }, + { + title: lang_user.spamfilter_table_rule, + data: 'value', + defaultContent: '' + }, + { + title: 'Scope', + data: 'object', + defaultContent: '' + } + ] + }); + } + function draw_bl_policy_domain_table() { + $('#bl_policy_domain_table').DataTable({ + responsive: true, + processing: true, + serverSide: false, + stateSave: true, + pageLength: pagination_size, + dom: "<'row'<'col-sm-12 col-md-6'f><'col-sm-12 col-md-6'l>>" + + "tr" + + "<'row'<'col-sm-12 col-md-5'i><'col-sm-12 col-md-7'p>>", + language: lang_datatables, + ajax: { + type: "GET", + url: '/api/v1/get/policy_bl_domain/' + table_for_domain, + dataSrc: function(data){ + $.each(data, function (i, item) { + if (!validateEmail(item.object)) { + item.chkbox = ''; + } + else { + item.chkbox = ''; + } + }); + + return data; + } + }, + columns: [ + { + // placeholder, so checkbox will not block child row toggle + title: '', + data: null, + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: '', + data: 'chkbox', + searchable: false, + orderable: false, + defaultContent: '' + }, + { + title: 'ID', + data: 'prefid', + defaultContent: '' + }, + { + title: lang_user.spamfilter_table_rule, + data: 'value', + defaultContent: '' + }, + { + title: 'Scope', + data: 'object', + defaultContent: '' + } + ] + }); + } + + + // detect element visibility changes + function onVisible(element, callback) { + $(document).ready(function() { + element_object = document.querySelector(element); + if (element_object === null) return; + + new IntersectionObserver((entries, observer) => { + entries.forEach(entry => { + if(entry.intersectionRatio > 0) { + callback(element_object); + observer.disconnect(); + } + }); + }).observe(element_object); + }); + } + // Draw Table if tab is active + onVisible("[id^=wl_policy_domain_table]", () => draw_wl_policy_domain_table()); + onVisible("[id^=bl_policy_domain_table]", () => draw_bl_policy_domain_table()); +}); diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index b93b1819..49cce1b2 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -77,7 +77,7 @@ $(document).ready(function() { $('.dns-modal-body').html(xhr.responseText); } }); - }); + }); // @Open Domain add modal $('#addDomainModal').on('show.bs.modal', function(e) { $.ajax({ @@ -85,24 +85,24 @@ $(document).ready(function() { data: {}, dataType: 'json', success: async function(data){ - $('#domain_templates').find('option').remove(); + $('#domain_templates').find('option').remove(); $('#domain_templates').selectpicker('destroy'); $('#domain_templates').selectpicker(); for (var i = 0; i < data.length; i++){ if (data[i].template === "Default"){ - $('#domain_templates').prepend($('