git subrepo commit (merge) mailcow/src/mailcow-dockerized
subrepo: subdir: "mailcow/src/mailcow-dockerized"
merged: "c7b1dc37"
upstream: origin: "https://github.com/mailcow/mailcow-dockerized.git"
branch: "master"
commit: "a366494c"
git-subrepo: version: "0.4.6"
origin: "???"
commit: "???"
Change-Id: Id574ecd4e02e3c4fbf8a1efd49be11c0b6d19a3f
diff --git a/mailcow/src/mailcow-dockerized/data/web/js/build/004-datatables.js b/mailcow/src/mailcow-dockerized/data/web/js/build/004-datatables.js
index 9ece8ea..8c79171 100644
--- a/mailcow/src/mailcow-dockerized/data/web/js/build/004-datatables.js
+++ b/mailcow/src/mailcow-dockerized/data/web/js/build/004-datatables.js
@@ -15801,7 +15801,7 @@
paginationEl.empty();
}
else {
- paginationEl = hostEl.html('<ul/>').children('ul').addClass('pagination');
+ paginationEl = hostEl.html('<ul/>').children('ul').addClass('pagination pagination-sm');
}
attach(
diff --git a/mailcow/src/mailcow-dockerized/data/web/js/build/013-mailcow.js b/mailcow/src/mailcow-dockerized/data/web/js/build/013-mailcow.js
index c734c82..fd60130 100644
--- a/mailcow/src/mailcow-dockerized/data/web/js/build/013-mailcow.js
+++ b/mailcow/src/mailcow-dockerized/data/web/js/build/013-mailcow.js
@@ -1,3 +1,13 @@
+const LOCALE = undefined;
+const DATETIME_FORMAT = {
+ year: "numeric",
+ month: "2-digit",
+ day: "2-digit",
+ hour: "2-digit",
+ minute: "2-digit",
+ second: "2-digit"
+};
+
$(document).ready(function() {
// mailcow alert box generator
window.mailcow_alert_box = function(message, type) {
@@ -12,14 +22,22 @@
$.notify({message: msg},{z_index: 20000, delay: auto_hide, type: type,placement: {from: "bottom",align: "right"},animate: {enter: 'animated fadeInUp',exit: 'animated fadeOutDown'}});
}
- $(".generate_password").click(function( event ) {
+ $(".generate_password").click(async function( event ) {
+ try {
+ var password_policy = await window.fetch("/api/v1/get/passwordpolicy", { method:'GET', cache:'no-cache' });
+ var password_policy = await password_policy.json();
+ random_passwd_length = password_policy.length;
+ } catch(err) {
+ var random_passwd_length = 8;
+ }
+
event.preventDefault();
$('[data-hibp]').trigger('input');
if (typeof($(this).closest("form").data('pwgen-length')) == "number") {
var random_passwd = GPW.pronounceable($(this).closest("form").data('pwgen-length'))
}
else {
- var random_passwd = GPW.pronounceable(8)
+ var random_passwd = GPW.pronounceable(random_passwd_length)
}
$(this).closest("form").find('[data-pwgen-field]').attr('type', 'text');
$(this).closest("form").find('[data-pwgen-field]').val(random_passwd);
@@ -103,10 +121,21 @@
if (lastTab) {
$('[data-bs-target="#' + lastTab + '"]').click();
var tab = $('[id^="' + lastTab + '"]');
- $(tab).find('.card-body.collapse').collapse('show');
+ $(tab).find('.card-body.collapse:first').collapse('show');
}
});
})();
+
+ // responsive tabs, scroll to opened tab
+ $(document).on("shown.bs.collapse shown.bs.tab", function (e) {
+ var target = $(e.target);
+ if($(window).width() <= 767) {
+ var offset = target.offset().top - 60;
+ $("html, body").stop().animate({
+ scrollTop: offset
+ }, 100);
+ }
+ });
// IE fix to hide scrollbars when table body is empty
$('tbody').filter(function (index) {
@@ -278,6 +307,8 @@
$.extend($.fn.dataTable.defaults, {
responsive: true
});
+ // disable default datatable click listener
+ $(document).off('click', 'tbody>tr');
// tag boxes
$('.tag-box .tag-add').click(function(){
@@ -294,19 +325,28 @@
$('#dark-mode-toggle').click(toggleDarkMode);
if ($('#dark-mode-theme').length) {
$('#dark-mode-toggle').prop('checked', true);
+ $('.main-logo').addClass('d-none');
+ $('.main-logo-dark').removeClass('d-none');
if ($('#rspamd_logo').length) $('#rspamd_logo').attr('src', '/img/rspamd_logo_light.png');
if ($('#rspamd_logo_sm').length) $('#rspamd_logo_sm').attr('src', '/img/rspamd_logo_light.png');
+ } else {
+ $('.main-logo').removeClass('d-none');
+ $('.main-logo-dark').addClass('d-none');
}
function toggleDarkMode(){
if($('#dark-mode-theme').length){
$('#dark-mode-theme').remove();
$('#dark-mode-toggle').prop('checked', false);
+ $('.main-logo').removeClass('d-none');
+ $('.main-logo-dark').addClass('d-none');
if ($('#rspamd_logo').length) $('#rspamd_logo').attr('src', '/img/rspamd_logo_dark.png');
if ($('#rspamd_logo_sm').length) $('#rspamd_logo_sm').attr('src', '/img/rspamd_logo_dark.png');
localStorage.setItem('theme', 'light');
}else{
$('head').append('<link id="dark-mode-theme" rel="stylesheet" type="text/css" href="/css/themes/mailcow-darkmode.css">');
$('#dark-mode-toggle').prop('checked', true);
+ $('.main-logo').addClass('d-none');
+ $('.main-logo-dark').removeClass('d-none');
if ($('#rspamd_logo').length) $('#rspamd_logo').attr('src', '/img/rspamd_logo_light.png');
if ($('#rspamd_logo_sm').length) $('#rspamd_logo_sm').attr('src', '/img/rspamd_logo_light.png');
localStorage.setItem('theme', 'dark');
diff --git a/mailcow/src/mailcow-dockerized/data/web/js/site/admin.js b/mailcow/src/mailcow-dockerized/data/web/js/site/admin.js
index d47a222..80da641 100644
--- a/mailcow/src/mailcow-dockerized/data/web/js/site/admin.js
+++ b/mailcow/src/mailcow-dockerized/data/web/js/site/admin.js
@@ -1,698 +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<r.length;)a=(t=r.charCodeAt(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<r.length;)t=this._keyStr.indexOf(r.charAt(d++))<<2|(a=this._keyStr.indexOf(r.charAt(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;e<r.length;e++){var o=r.charCodeAt(e);o<128?t+=String.fromCharCode(o):o>127&&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;e<r.length;)(o=r.charCodeAt(e))<128?(t+=String.fromCharCode(o),e++):o>191&&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<B.length-1);return i.toFixed(1)+" "+B[e]}
- function hashCode(t){for(var n=0,r=0;r<t.length;r++)n=t.charCodeAt(r)+((n<<5)-n);return n}
- function intToRGB(t){var n=(16777215&t).toString(16).toUpperCase();return"00000".substring(0,6-n.length)+n}
- $("#dkim_missing_keys").on('click', function(e) {
- e.preventDefault();
- var domains = [];
- $('.dkim_missing').each(function() {
- domains.push($(this).val());
- });
- $('#dkim_add_domains').val(domains);
- });
- $(".arrow-toggle").on('click', function(e) { e.preventDefault(); $(this).find('.arrow').toggleClass("animation"); });
- $("#mass_exclude").change(function(){ $("#mass_include").selectpicker('deselectAll'); });
- $("#mass_include").change(function(){ $("#mass_exclude").selectpicker('deselectAll'); });
- $("#mass_disarm").click(function() { $("#mass_send").attr("disabled", !this.checked); });
- $(".admin-ays-dialog").click(function() { return confirm(lang.ays); });
- $(".validate_rspamd_regex").click(function( event ) {
- event.preventDefault();
- var regex_map_id = $(this).data('regex-map');
- var regex_data = $(jq(regex_map_id)).val().split(/\r?\n/);
- var regex_valid = true;
- for(var i = 0;i < regex_data.length;i++){
- if(regex_data[i].startsWith('#') || !regex_data[i]){
- continue;
- }
- if(!validateRegex(regex_data[i])) {
- mailcow_alert_box('Cannot build regex from line ' + (i+1), 'danger');
- var regex_valid = false;
- break;
- }
- if(!regex_data[i].startsWith('/') || !/\/[ims]?$/.test(regex_data[i])){
- mailcow_alert_box('Line ' + (i+1) + ' is invalid', 'danger');
- var regex_valid = false;
- break;
- }
- }
- if (regex_valid) {
- mailcow_alert_box('Regex OK', 'success');
- $('button[data-id="' + regex_map_id + '"]').attr({"disabled": false});
- }
- });
- $('.textarea-code').on('keyup', function() {
- $('.submit_rspamd_regex').attr({"disabled": true});
- });
- $("#show_rspamd_global_filters").click(function() {
- $.get("inc/ajax/show_rspamd_global_filters.php");
- $("#confirm_show_rspamd_global_filters").hide();
- $("#rspamd_global_filters").removeClass("d-none");
- });
- $("#super_delete").click(function() { return confirm(lang.queue_ays); });
-
- $(".refresh_table").on('click', function(e) {
- e.preventDefault();
- var table_name = $(this).data('table');
- $('#' + table_name).DataTable().ajax.reload();
- });
- function draw_domain_admins() {
- // just recalc width if instance already exists
- if ($.fn.DataTable.isDataTable('#domainadminstable') ) {
- $('#domainadminstable').DataTable().columns.adjust().responsive.recalc();
- return;
- }
-
- $('#domainadminstable').DataTable({
- processing: true,
- serverSide: false,
- 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 '<i class="bi bi-check-lg"></i>';
- else return '<i class="bi bi-x-lg"></i>'
- }
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- render: function (data, type) {
- if(data == 1) return '<i class="bi bi-check-lg"></i>';
- else return '<i class="bi bi-x-lg"></i>'
- }
- },
- {
- 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({
- processing: true,
- serverSide: false,
- 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({
- processing: true,
- serverSide: false,
- 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 '<i class="bi bi-check-lg"></i>';
- else return '<i class="bi bi-x-lg"></i>'
- }
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- render: function (data, type) {
- if(data == 1) return '<i class="bi bi-check-lg"></i>';
- else return '<i class="bi bi-x-lg"></i>'
- }
- },
- {
- 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({
- processing: true,
- serverSide: false,
- 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: ''
- },
- {
- 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({
- processing: true,
- serverSide: false,
- 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 '<i class="bi bi-check-lg"></i>';
- else return '<i class="bi bi-x-lg"></i>'
- }
- },
- {
- 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({
- processing: true,
- serverSide: false,
- 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 '<i class="bi bi-check-lg"></i>';
- else return '<i class="bi bi-x-lg"></i>'
- }
- },
- {
- 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 = '<div class="btn-group">' +
- '<a href="#" data-bs-toggle="modal" data-bs-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="sender-dependent" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-caret-right-fill"></i> Test</a>' +
- '<a href="/edit/relayhost/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-rlyhost" data-api-url="delete/relayhost" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- 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 + '<hr style="margin:5px 0px 5px 0px;">' + item.used_by_domains; }
- item.chkbox = '<input type="checkbox" data-id="rlyhosts" name="multi_select" value="' + item.id + '" />';
- });
- } else if (table == 'transportstable') {
- $.each(data, function (i, item) {
- if (item.is_mx_based) {
- item.destination = '<i class="bi bi-info-circle-fill text-info mx-info" data-bs-toggle="tooltip" title="' + lang.is_mx_based + '"></i> <code>' + item.destination + '</code>';
- }
- if (item.username) {
- item.username = '<i style="color:#' + intToRGB(hashCode(item.nexthop)) + ';" class="bi bi-square-fill"></i> ' + item.username;
- }
- item.action = '<div class="btn-group">' +
- '<a href="#" data-bs-toggle="modal" data-bs-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="transport-map" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-caret-right-fill"></i> Test</a>' +
- '<a href="/edit/transport/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-transport" data-api-url="delete/transport" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- item.chkbox = '<input type="checkbox" data-id="transports" name="multi_select" value="' + item.id + '" />';
- });
- } else if (table == 'queuetable') {
- $.each(data, function (i, item) {
- item.chkbox = '<input type="checkbox" data-id="mailqitems" name="multi_select" value="' + item.queue_id + '" />';
- rcpts = $.map(item.recipients, function(i) {
- return escapeHtml(i);
- });
- item.recipients = rcpts.join('<hr style="margin:1px!important">');
- item.action = '<div class="btn-group">' +
- '<a href="#" data-bs-toggle="modal" data-bs-target="#showQueuedMsg" data-queue-id="' + encodeURI(item.queue_id) + '" class="btn btn-xs btn-secondary">' + lang.queue_show_message + '</a>' +
- '</div>';
- });
- } else if (table == 'forwardinghoststable') {
- $.each(data, function (i, item) {
- item.action = '<div class="btn-group">' +
- '<a href="#" data-action="delete_selected" data-id="single-fwdhost" data-api-url="delete/fwdhost" data-item="' + encodeURI(item.host) + '" class="btn btn-xs btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- item.chkbox = '<input type="checkbox" data-id="fwdhosts" name="multi_select" value="' + item.host + '" />';
- });
- } else if (table == 'oauth2clientstable') {
- $.each(data, function (i, item) {
- item.action = '<div class="btn-group">' +
- '<a href="/edit.php?oauth2client=' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-oauth2-client" data-api-url="delete/oauth2-client" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- item.scope = "profile";
- item.grant_types = 'refresh_token password authorization_code';
- item.chkbox = '<input type="checkbox" data-id="oauth2_clients" name="multi_select" value="' + item.id + '" />';
- });
- } 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, "<br>");
- item.chkbox = '<input type="checkbox" data-id="domain_admins" name="multi_select" value="' + item.username + '" />';
- item.action = '<div class="btn-group">' +
- '<a href="/edit/domainadmin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-domain-admin" data-api-url="delete/domain-admin" data-item="' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-xs-third btn-success"><i class="bi bi-person-fill"></i> Login</a>' +
- '</div>';
- });
- } else if (table == 'adminstable') {
- $.each(data, function (i, item) {
- if (admin_username.toLowerCase() == item.username.toLowerCase()) {
- item.usr = '<i class="bi bi-person-check"></i> ' + item.username;
- } else {
- item.usr = item.username;
- }
- item.chkbox = '<input type="checkbox" data-id="admins" name="multi_select" value="' + item.username + '" />';
- item.action = '<div class="btn-group">' +
- '<a href="/edit/admin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-admin" data-api-url="delete/admin" data-item="' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- });
- }
- 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('<i class="bi bi-arrow-repeat icon-spin"></i> ');
- $.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('<div class="spinner-border" role="status"><span class="visually-hidden">Loading...</span></div> ');
- $.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 = $('<tr />');
- if (type == "app_link") {
- cols = '<td><input class="input-sm input-xs-lg form-control" data-id="app_links" type="text" name="app" required></td>';
- cols += '<td><input class="input-sm input-xs-lg form-control" data-id="app_links" type="text" name="href" required></td>';
- cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-secondary h-100 w-100" type="button">' + lang.remove_row + '</a></td>';
- } else if (type == "f2b_regex") {
- cols = '<td><input style="text-align:center" class="input-sm input-xs-lg form-control" data-id="f2b_regex" type="text" value="+" disabled></td>';
- cols += '<td><input class="input-sm input-xs-lg form-control regex-input" data-id="f2b_regex" type="text" name="regex" required></td>';
- cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-secondary h-100 w-100" type="button">' + lang.remove_row + '</a></td>';
- }
- 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<r.length;)a=(t=r.charCodeAt(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<r.length;)t=this._keyStr.indexOf(r.charAt(d++))<<2|(a=this._keyStr.indexOf(r.charAt(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;e<r.length;e++){var o=r.charCodeAt(e);o<128?t+=String.fromCharCode(o):o>127&&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;e<r.length;)(o=r.charCodeAt(e))<128?(t+=String.fromCharCode(o),e++):o>191&&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<B.length-1);return i.toFixed(1)+" "+B[e]}
+ function hashCode(t){for(var n=0,r=0;r<t.length;r++)n=t.charCodeAt(r)+((n<<5)-n);return n}
+ function intToRGB(t){var n=(16777215&t).toString(16).toUpperCase();return"00000".substring(0,6-n.length)+n}
+ $("#dkim_missing_keys").on('click', function(e) {
+ e.preventDefault();
+ var domains = [];
+ $('.dkim_missing').each(function() {
+ domains.push($(this).val());
+ });
+ $('#dkim_add_domains').val(domains);
+ });
+ $(".arrow-toggle").on('click', function(e) { e.preventDefault(); $(this).find('.arrow').toggleClass("animation"); });
+ $("#mass_exclude").change(function(){ $("#mass_include").selectpicker('deselectAll'); });
+ $("#mass_include").change(function(){ $("#mass_exclude").selectpicker('deselectAll'); });
+ $("#mass_disarm").click(function() { $("#mass_send").attr("disabled", !this.checked); });
+ $(".admin-ays-dialog").click(function() { return confirm(lang.ays); });
+ $(".validate_rspamd_regex").click(function( event ) {
+ event.preventDefault();
+ var regex_map_id = $(this).data('regex-map');
+ var regex_data = $(jq(regex_map_id)).val().split(/\r?\n/);
+ var regex_valid = true;
+ for(var i = 0;i < regex_data.length;i++){
+ if(regex_data[i].startsWith('#') || !regex_data[i]){
+ continue;
+ }
+ if(!validateRegex(regex_data[i])) {
+ mailcow_alert_box('Cannot build regex from line ' + (i+1), 'danger');
+ var regex_valid = false;
+ break;
+ }
+ if(!regex_data[i].startsWith('/') || !/\/[ims]?$/.test(regex_data[i])){
+ mailcow_alert_box('Line ' + (i+1) + ' is invalid', 'danger');
+ var regex_valid = false;
+ break;
+ }
+ }
+ if (regex_valid) {
+ mailcow_alert_box('Regex OK', 'success');
+ $('button[data-id="' + regex_map_id + '"]').attr({"disabled": false});
+ }
+ });
+ $('.textarea-code').on('keyup', function() {
+ $('.submit_rspamd_regex').attr({"disabled": true});
+ });
+ $("#show_rspamd_global_filters").click(function() {
+ $.get("inc/ajax/show_rspamd_global_filters.php");
+ $("#confirm_show_rspamd_global_filters").hide();
+ $("#rspamd_global_filters").removeClass("d-none");
+ });
+ $("#super_delete").click(function() { return confirm(lang.queue_ays); });
+
+ $(".refresh_table").on('click', function(e) {
+ e.preventDefault();
+ var table_name = $(this).data('table');
+ $('#' + table_name).DataTable().ajax.reload();
+ });
+ function draw_domain_admins() {
+ // just recalc width if instance already exists
+ if ($.fn.DataTable.isDataTable('#domainadminstable') ) {
+ $('#domainadminstable').DataTable().columns.adjust().responsive.recalc();
+ return;
+ }
+
+ $('#domainadminstable').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/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 '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
+ else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ render: function (data, type) {
+ if(data == 1) return '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
+ else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-text-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: 'dt-sm-head-hidden dt-text-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 '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
+ else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ render: function (data, type) {
+ if(data == 1) return '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
+ else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ defaultContent: '',
+ className: 'dt-sm-head-hidden dt-text-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?'<i class="bi bi-x-lg"><span class="sorting-value">yes</span></i>':'no'==data&&'<i class="bi bi-check-lg"><span class="sorting-value">no</span></i>';
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-text-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 '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
+ else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-text-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 '<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>';
+ else return '<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-text-right',
+ defaultContent: ''
+ },
+ ]
+ });
+ }
+
+ function process_table_data(data, table) {
+ if (table == 'relayhoststable') {
+ $.each(data, function (i, item) {
+ item.action = '<div class="btn-group">' +
+ '<a href="#" data-bs-toggle="modal" data-bs-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="sender-dependent" class="btn btn-xs btn-xs-lg btn-xs-third btn-secondary"><i class="bi bi-caret-right-fill"></i> Test</a>' +
+ '<a href="/edit/relayhost/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-lg btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-rlyhost" data-api-url="delete/relayhost" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-lg btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ 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 + '<hr style="margin:5px 0px 5px 0px;">' + item.used_by_domains; }
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="rlyhosts" name="multi_select" value="' + item.id + '" />';
+ });
+ } else if (table == 'transportstable') {
+ $.each(data, function (i, item) {
+ if (item.is_mx_based) {
+ item.destination = '<i class="bi bi-info-circle-fill text-info mx-info" data-bs-toggle="tooltip" title="' + lang.is_mx_based + '"></i> <code>' + item.destination + '</code>';
+ }
+ if (item.username) {
+ item.username = '<i style="color:#' + intToRGB(hashCode(item.nexthop)) + ';" class="bi bi-square-fill"></i> ' + item.username;
+ }
+ item.action = '<div class="btn-group">' +
+ '<a href="#" data-bs-toggle="modal" data-bs-target="#testTransportModal" data-transport-id="' + encodeURI(item.id) + '" data-transport-type="transport-map" class="btn btn-xs btn-xs-lg btn-xs-third btn-secondary"><i class="bi bi-caret-right-fill"></i> Test</a>' +
+ '<a href="/edit/transport/' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-lg btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-transport" data-api-url="delete/transport" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-lg btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="transports" name="multi_select" value="' + item.id + '" />';
+ });
+ } else if (table == 'queuetable') {
+ $.each(data, function (i, item) {
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="mailqitems" name="multi_select" value="' + item.queue_id + '" />';
+ rcpts = $.map(item.recipients, function(i) {
+ return escapeHtml(i);
+ });
+ item.recipients = rcpts.join('<hr style="margin:1px!important">');
+ item.action = '<div class="btn-group">' +
+ '<a href="#" data-bs-toggle="modal" data-bs-target="#showQueuedMsg" data-queue-id="' + encodeURI(item.queue_id) + '" class="btn btn-xs btn-xs-lg btn-secondary">' + lang.queue_show_message + '</a>' +
+ '</div>';
+ });
+ } else if (table == 'forwardinghoststable') {
+ $.each(data, function (i, item) {
+ item.action = '<div class="btn-group">' +
+ '<a href="#" data-action="delete_selected" data-id="single-fwdhost" data-api-url="delete/fwdhost" data-item="' + encodeURI(item.host) + '" class="btn btn-xs btn-xs-lg btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="fwdhosts" name="multi_select" value="' + item.host + '" />';
+ });
+ } else if (table == 'oauth2clientstable') {
+ $.each(data, function (i, item) {
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit.php?oauth2client=' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-oauth2-client" data-api-url="delete/oauth2-client" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ item.scope = "profile";
+ item.grant_types = 'refresh_token password authorization_code';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="oauth2_clients" name="multi_select" value="' + item.id + '" />';
+ });
+ } 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, "<br>");
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="domain_admins" name="multi_select" value="' + item.username + '" />';
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit/domainadmin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-lg btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-domain-admin" data-api-url="delete/domain-admin" data-item="' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-lg btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-xs-lg btn-xs-third btn-success"><i class="bi bi-person-fill"></i> Login</a>' +
+ '</div>';
+ });
+ } else if (table == 'adminstable') {
+ $.each(data, function (i, item) {
+ if (admin_username.toLowerCase() == item.username.toLowerCase()) {
+ item.usr = '<i class="bi bi-person-check"></i> ' + item.username;
+ } else {
+ item.usr = item.username;
+ }
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="admins" name="multi_select" value="' + item.username + '" />';
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit/admin/' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-admin" data-api-url="delete/admin" data-item="' + encodeURI(item.username) + '" class="btn btn-xs btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ });
+ }
+ 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('<i class="bi bi-arrow-repeat icon-spin"></i> ');
+ $.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('<div class="spinner-border" role="status"><span class="visually-hidden">Loading...</span></div> ');
+ $.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 = $('<tr />');
+ if (type == "app_link") {
+ cols = '<td><input class="input-sm input-xs-lg form-control" data-id="app_links" type="text" name="app" required></td>';
+ cols += '<td><input class="input-sm input-xs-lg form-control" data-id="app_links" type="text" name="href" required></td>';
+ cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-secondary h-100 w-100" type="button">' + lang.remove_row + '</a></td>';
+ } else if (type == "f2b_regex") {
+ cols = '<td><input style="text-align:center" class="input-sm input-xs-lg form-control" data-id="f2b_regex" type="text" value="+" disabled></td>';
+ cols += '<td><input class="input-sm input-xs-lg form-control regex-input" data-id="f2b_regex" type="text" name="regex" required></td>';
+ cols += '<td><a href="#" role="button" class="btn btn-sm btn-xs-lg btn-secondary h-100 w-100" type="button">' + lang.remove_row + '</a></td>';
+ }
+ 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/mailcow/src/mailcow-dockerized/data/web/js/site/debug.js b/mailcow/src/mailcow-dockerized/data/web/js/site/debug.js
index 85e6b78..10b1e8c 100644
--- a/mailcow/src/mailcow-dockerized/data/web/js/site/debug.js
+++ b/mailcow/src/mailcow-dockerized/data/web/js/site/debug.js
@@ -1,13 +1,3 @@
-const LOCALE = undefined;
-const DATETIME_FORMAT = {
- year: "numeric",
- month: "2-digit",
- day: "2-digit",
- hour: "2-digit",
- minute: "2-digit",
- second: "2-digit"
-};
-
$(document).ready(function() {
// Parse seconds ago to date
// Get "now" timestamp
@@ -34,7 +24,7 @@
});
// set update loop container list
- containersToUpdate = {}
+ containersToUpdate = {};
// set default ChartJs Font Color
Chart.defaults.color = '#999';
// create host cpu and mem charts
@@ -43,15 +33,47 @@
if (mailcow_info.branch === "master"){
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")
+ $("#mailcow_version").click(function(){
+ 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
- get_public_ips();
+ $("#host_show_ip").click(function(){
+ $("#host_show_ip").find(".text").addClass("d-none");
+ $("#host_show_ip").find(".spinner-border").removeClass("d-none");
+
+ 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);
+
+ // display host ips
+ if (data.ipv4)
+ $("#host_ipv4").text(data.ipv4);
+ if (data.ipv6)
+ $("#host_ipv6").text(data.ipv6);
+
+ $("#host_show_ip").addClass("d-none");
+ $("#host_show_ip").find(".text").removeClass("d-none");
+ $("#host_show_ip").find(".spinner-border").addClass("d-none");
+ $("#host_ipv4").removeClass("d-none");
+ $("#host_ipv6").removeClass("d-none");
+ $("#host_ipv6").removeClass("text-danger");
+ $("#host_ipv4").addClass("d-block");
+ $("#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");
+ $("#host_ipv6").text(lang_debug.error_show_ip);
+ $("#host_show_ip").find(".text").removeClass("d-none");
+ $("#host_show_ip").find(".spinner-border").addClass("d-none");
+ });
+ });
update_container_stats();
});
jQuery(function($){
@@ -85,11 +107,20 @@
return;
}
- $('#autodiscover_log').DataTable({
+ var table = $('#autodiscover_log').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-autodiscover-logs', '#autodiscover_log');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/autodiscover/100",
@@ -134,6 +165,10 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-autodiscover-logs', '#autodiscover_log');
+ });
}
function draw_postfix_logs() {
// just recalc width if instance already exists
@@ -142,11 +177,20 @@
return;
}
- $('#postfix_log').DataTable({
+ var table = $('#postfix_log').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-postfix-logs', '#postfix_log');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/postfix",
@@ -176,6 +220,10 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-postfix-logs', '#postfix_log');
+ });
}
function draw_watchdog_logs() {
// just recalc width if instance already exists
@@ -184,11 +232,20 @@
return;
}
- $('#watchdog_log').DataTable({
+ var table = $('#watchdog_log').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-watchdog-logs', '#watchdog_log');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/watchdog",
@@ -222,6 +279,10 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-watchdog-logs', '#watchdog_log');
+ });
}
function draw_api_logs() {
// just recalc width if instance already exists
@@ -230,11 +291,20 @@
return;
}
- $('#api_log').DataTable({
+ var table = $('#api_log').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-api-logs', '#api_log');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/api",
@@ -275,6 +345,10 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-api-logs', '#api_log');
+ });
}
function draw_rl_logs() {
// just recalc width if instance already exists
@@ -283,11 +357,20 @@
return;
}
- $('#rl_log').DataTable({
+ var table = $('#rl_log').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-rl-logs', '#rl_log');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/ratelimited",
@@ -366,6 +449,10 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-rl-logs', '#rl_log');
+ });
}
function draw_ui_logs() {
// just recalc width if instance already exists
@@ -374,11 +461,20 @@
return;
}
- $('#ui_logs').DataTable({
+ var table = $('#ui_logs').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-ui-logs', '#ui_logs');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/ui",
@@ -437,6 +533,10 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-ui-logs', '#ui_log');
+ });
}
function draw_sasl_logs() {
// just recalc width if instance already exists
@@ -445,11 +545,20 @@
return;
}
- $('#sasl_logs').DataTable({
+ var table = $('#sasl_logs').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-sasl-logs', '#sasl_logs');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/sasl",
@@ -479,12 +588,16 @@
data: 'datetime',
defaultContent: '',
createdCell: function(td, cellData) {
- cellData = Math.floor((new Date(data.replace(/-/g, "/"))).getTime() / 1000);
+ cellData = Math.floor((new Date(cellData.replace(/-/g, "/"))).getTime() / 1000);
createSortableDate(td, cellData)
}
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-sasl-logs', '#sasl_logs');
+ });
}
function draw_acme_logs() {
// just recalc width if instance already exists
@@ -493,11 +606,20 @@
return;
}
- $('#acme_log').DataTable({
+ var table = $('#acme_log').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-acme-logs', '#acme_log');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/acme",
@@ -522,6 +644,10 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-acme-logs', '#acme_log');
+ });
}
function draw_netfilter_logs() {
// just recalc width if instance already exists
@@ -530,11 +656,20 @@
return;
}
- $('#netfilter_log').DataTable({
+ var table = $('#netfilter_log').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-netfilter-logs', '#netfilter_log');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/netfilter",
@@ -564,6 +699,10 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-netfilter-logs', '#netfilter_log');
+ });
}
function draw_sogo_logs() {
// just recalc width if instance already exists
@@ -572,11 +711,20 @@
return;
}
- $('#sogo_log').DataTable({
+ var table = $('#sogo_log').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-sogo-logs', '#sogo_log');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/sogo",
@@ -606,6 +754,10 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-sogo-logs', '#sogo_log');
+ });
}
function draw_dovecot_logs() {
// just recalc width if instance already exists
@@ -614,11 +766,20 @@
return;
}
- $('#dovecot_log').DataTable({
+ var table = $('#dovecot_log').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-dovecot-logs', '#dovecot_log');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/dovecot",
@@ -648,19 +809,20 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-dovecot-logs', '#dovecot_log');
+ });
}
function rspamd_pie_graph() {
$.ajax({
url: '/api/v1/get/rspamd/actions',
async: true,
success: function(data){
- console.log(data);
-
var total = 0;
$(data).map(function(){total += this[1];});
var labels = $.makeArray($(data).map(function(){return this[0] + ' ' + Math.round(this[1]/total * 100) + '%';}));
var values = $.makeArray($(data).map(function(){return this[1];}));
- console.log(values);
var graphdata = {
labels: labels,
@@ -717,11 +879,20 @@
return;
}
- $('#rspamd_history').DataTable({
+ var table = $('#rspamd_history').DataTable({
+ 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>>",
language: lang_datatables,
order: [[0, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-rspamd-logs', '#rspamd_history');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/logs/rspamd-history",
@@ -767,12 +938,15 @@
title: 'Score',
data: 'score',
defaultContent: '',
+ class: 'text-nowrap',
createdCell: function(td, cellData) {
$(td).attr({
"data-order": cellData.sortBy,
"data-sort": cellData.sortBy
});
- $(td).html(cellData.value);
+ },
+ render: function (data) {
+ return data.value;
}
},
{
@@ -795,7 +969,9 @@
"data-order": cellData.sortBy,
"data-sort": cellData.sortBy
});
- $(td).html(cellData.value);
+ },
+ render: function (data) {
+ return data.value;
}
},
{
@@ -810,6 +986,10 @@
}
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-rspamd-history', '#rspamd_history');
+ });
}
function process_table_data(data, table) {
if (table == 'rspamd_history') {
@@ -821,31 +1001,31 @@
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 = '(<span class="text-success"><b>' + sym.score + '</b></span>)'
+ sym.score_formatted = '(<span class="text-success"><b>' + sym.score + '</b></span>)';
}
else if (sym.score === 0) {
- sym.score_formatted = '(<span><b>' + sym.score + '</b></span>)'
+ sym.score_formatted = '(<span><b>' + sym.score + '</b></span>)';
}
else {
- sym.score_formatted = '(<span class="text-danger"><b>' + sym.score + '</b></span>)'
+ sym.score_formatted = '(<span class="text-danger"><b>' + sym.score + '</b></span>)';
}
var str = '<strong>' + key + '</strong> ' + sym.score_formatted;
if (sym.options) {
str += ' [' + escapeHtml(sym.options.join(", ")) + "]";
}
- return str
+ return str;
}).join('<br>\n');
item.subject = escapeHtml(item.subject);
var scan_time = item.time_real.toFixed(3);
@@ -978,14 +1158,14 @@
}
});
}
- 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;
@@ -993,7 +1173,7 @@
if (table = $('#' + log_table).DataTable()) {
var heading = $('#' + log_table).closest('.card').find('.card-header');
- var load_rows = (table.page.len() + 1) + '-' + (table.page.len() + new_nrows)
+ var load_rows = (table.data().count() + 1) + '-' + (table.data().count() + new_nrows)
$.get('/api/v1/get/logs/' + log_url + '/' + load_rows).then(function(data){
if (data.length === undefined) { mailcow_alert_box(lang.no_new_rows, "info"); return; }
@@ -1005,6 +1185,12 @@
});
}
})
+ function hideTableExpandCollapseBtn(tab, table){
+ if ($(table).hasClass('collapsed'))
+ $(tab).find(".table_collapse_option").show();
+ else
+ $(tab).find(".table_collapse_option").hide();
+ }
// detect element visibility changes
function onVisible(element, callback) {
@@ -1037,7 +1223,6 @@
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
@@ -1109,6 +1294,12 @@
$("#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('<span data-bs-toggle="tooltip" data-bs-placement="top" title="' + lang_debug.wip +'">' + data.architecture + ' ⚠️</span>');
+ }
+ else {
+ $("#host_architecture").html(data.architecture);
+ }
// update cpu and mem chart
var cpu_chart = Chart.getChart("host_cpu_chart");
@@ -1120,9 +1311,9 @@
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();
@@ -1224,20 +1415,6 @@
// 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);
-
- // display host ips
- if (data.ipv4)
- $("#host_ipv4").text(data.ipv4);
- if (data.ipv6)
- $("#host_ipv6").text(data.ipv6);
- });
-}
// format hosts uptime seconds to readable string
function formatUptime(seconds){
seconds = Number(seconds);
@@ -1295,23 +1472,23 @@
};
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
}
}
}
@@ -1359,13 +1536,13 @@
};
var optionsCpu = {
interaction: {
- mode: 'index'
+ mode: 'index'
},
scales: {
yAxis: {
min: 0,
grid: {
- display: false
+ display: false
},
ticks: {
callback: function(i, index, ticks) {
@@ -1375,7 +1552,7 @@
},
xAxis: {
grid: {
- display: false
+ display: false
}
}
}
@@ -1397,13 +1574,13 @@
};
var optionsMem = {
interaction: {
- mode: 'index'
+ mode: 'index'
},
scales: {
yAxis: {
min: 0,
grid: {
- display: false
+ display: false
},
ticks: {
callback: function(i, index, ticks) {
@@ -1413,7 +1590,7 @@
},
xAxis: {
grid: {
- display: false
+ display: false
}
}
}
@@ -1509,22 +1686,22 @@
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 '<a href="' + matched + '" target="_blank">' + last_uri_path + '</a><br>';
- };
+ return '<a href="' + matched + '" target="_blank">' + last_uri_path + '</a><br>';
+ };
- // if it's not a github link, return complete link
- return '<a href="' + matched + '" target="_blank">' + matched + '</a>';
+ // if it's not a github link, return complete link
+ return '<a href="' + matched + '" target="_blank">' + matched + '</a>';
});
return replacedText;
diff --git a/mailcow/src/mailcow-dockerized/data/web/js/site/edit.js b/mailcow/src/mailcow-dockerized/data/web/js/site/edit.js
index 55a8e6b..cd938cd 100644
--- a/mailcow/src/mailcow-dockerized/data/web/js/site/edit.js
+++ b/mailcow/src/mailcow-dockerized/data/web/js/site/edit.js
@@ -1,210 +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({
- processing: true,
- serverSide: false,
- 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 = '<input type="checkbox" data-id="policy_wl_domain" name="multi_select" value="' + item.prefid + '" />';
- }
- else {
- item.chkbox = '<input type="checkbox" disabled title="' + lang_user.spamfilter_table_domain_policy + '" />';
- }
- });
-
- 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({
- processing: true,
- serverSide: false,
- 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 = '<input type="checkbox" data-id="policy_bl_domain" name="multi_select" value="' + item.prefid + '" />';
- }
- else {
- item.chkbox = '<input type="checkbox" disabled tooltip="' + lang_user.spamfilter_table_domain_policy + '" />';
- }
- });
-
- 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 = '<input type="checkbox" class="form-check-input" data-id="policy_wl_domain" name="multi_select" value="' + item.prefid + '" />';
+ }
+ else {
+ item.chkbox = '<input type="checkbox" class="form-check-input" disabled title="' + lang_user.spamfilter_table_domain_policy + '" />';
+ }
+ });
+
+ 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 = '<input type="checkbox" class="form-check-input" data-id="policy_bl_domain" name="multi_select" value="' + item.prefid + '" />';
+ }
+ else {
+ item.chkbox = '<input type="checkbox" class="form-check-input" disabled tooltip="' + lang_user.spamfilter_table_domain_policy + '" />';
+ }
+ });
+
+ 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/mailcow/src/mailcow-dockerized/data/web/js/site/mailbox.js b/mailcow/src/mailcow-dockerized/data/web/js/site/mailbox.js
index 12c4bb4..c2b1761 100644
--- a/mailcow/src/mailcow-dockerized/data/web/js/site/mailbox.js
+++ b/mailcow/src/mailcow-dockerized/data/web/js/site/mailbox.js
@@ -77,7 +77,7 @@
$('.dns-modal-body').html(xhr.responseText);
}
});
- });
+ });
// @Open Domain add modal
$('#addDomainModal').on('show.bs.modal', function(e) {
$.ajax({
@@ -85,24 +85,24 @@
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($('<option>', {
- 'value': data[i].id,
- 'text': data[i].template,
- 'data-attributes': JSON.stringify(data[i].attributes),
- 'selected': true
+ $('#domain_templates').prepend($('<option>', {
+ 'value': data[i].id,
+ 'text': data[i].template,
+ 'data-attributes': JSON.stringify(data[i].attributes),
+ 'selected': true
}));
setDomainTemplateData(data[i].attributes);
} else {
- $('#domain_templates').append($('<option>', {
- 'value': data[i].id,
- 'text': data[i].template,
- 'data-attributes': JSON.stringify(data[i].attributes),
- 'selected': false
+ $('#domain_templates').append($('<option>', {
+ 'value': data[i].id,
+ 'text': data[i].template,
+ 'data-attributes': JSON.stringify(data[i].attributes),
+ 'selected': false
}));
}
};
@@ -127,24 +127,24 @@
data: {},
dataType: 'json',
success: async function(data){
- $('#mailbox_templates').find('option').remove();
+ $('#mailbox_templates').find('option').remove();
$('#mailbox_templates').selectpicker('destroy');
$('#mailbox_templates').selectpicker();
for (var i = 0; i < data.length; i++){
if (data[i].template === "Default"){
- $('#mailbox_templates').prepend($('<option>', {
- 'value': data[i].id,
- 'text': data[i].template,
- 'data-attributes': JSON.stringify(data[i].attributes),
- 'selected': true
+ $('#mailbox_templates').prepend($('<option>', {
+ 'value': data[i].id,
+ 'text': data[i].template,
+ 'data-attributes': JSON.stringify(data[i].attributes),
+ 'selected': true
}));
setMailboxTemplateData(data[i].attributes);
} else {
- $('#mailbox_templates').append($('<option>', {
- value: data[i].id,
- text : data[i].template,
- 'data-attributes': JSON.stringify(data[i].attributes),
- 'selected': false
+ $('#mailbox_templates').append($('<option>', {
+ value: data[i].id,
+ text : data[i].template,
+ 'data-attributes': JSON.stringify(data[i].attributes),
+ 'selected': false
}));
}
};
@@ -229,20 +229,20 @@
} else {
$('#addDomain_gal').prop('checked', false);
}
-
+
if (template.active == 1){
$('#addDomain_active').prop('checked', true);
} else {
$('#addDomain_active').prop('checked', false);
}
-
+
$("#addDomain_rl_value").val(template.rl_value);
$('#addDomain_rl_frame').selectpicker('val', template.rl_frame);
$("#dkim_selector").val(template.dkim_selector);
if (!template.key_size)
template.key_size = 2048;
$('#key_size').selectpicker('val', template.key_size.toString());
-
+
if (template.backupmx == 1){
$('#addDomain_relay_domain').prop('checked', true);
} else {
@@ -259,7 +259,7 @@
$('#addDomain_relay_unknown_only').prop('checked', false);
}
-
+
// load tags
$('#addDomain_tags').val("");
$($('#addDomain_tags').parent().find(".tag-values")[0]).val("");
@@ -404,7 +404,7 @@
} else {
$('#sogo_access').prop('checked', false);
}
-
+
// load tags
$('#addMailbox_tags').val("");
$($('#addMailbox_tags').parent().find(".tag-values")[0]).val("");
@@ -417,11 +417,11 @@
// http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
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<B.length-1);return i.toFixed(1)+" "+B[e]}
function unix_time_format(i){return""==i?'<i class="bi bi-x"></i>':new Date(i?1e3*i:0).toLocaleDateString(void 0,{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit"})}
-
+
$(".refresh_table").on('click', function(e) {
e.preventDefault();
var table_name = $(this).data('table');
-
+
if ($.fn.DataTable.isDataTable('#' + table_name))
$('#' + table_name).DataTable().ajax.reload();
});
@@ -433,9 +433,18 @@
}
var table = $('#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,
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-domains', '#domain_table');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/domain/all",
@@ -457,16 +466,16 @@
item.def_quota_for_mbox = humanFileSize(item.def_quota_for_mbox);
item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
- item.chkbox = '<input type="checkbox" data-id="domain" name="multi_select" value="' + encodeURIComponent(item.domain_name) + '" />';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="domain" name="multi_select" value="' + encodeURIComponent(item.domain_name) + '" />';
item.action = '<div class="btn-group">';
if (role == "admin") {
- item.action += '<a href="/edit/domain/' + encodeURIComponent(item.domain_name) + '" class="btn btn-sm btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-domain" data-api-url="delete/domain" data-item="' + encodeURIComponent(item.domain_name) + '" class="btn btn-sm btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '<a href="#dnsInfoModal" class="btn btn-sm btn-info" data-bs-toggle="modal" data-domain="' + encodeURIComponent(item.domain_name) + '"><i class="bi bi-globe2"></i> DNS</a></div>';
+ item.action += '<a href="/edit/domain/' + encodeURIComponent(item.domain_name) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-domain" data-api-url="delete/domain" data-item="' + encodeURIComponent(item.domain_name) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="#dnsInfoModal" class="btn btn-sm btn-xs-lg btn-info" data-bs-toggle="modal" data-domain="' + encodeURIComponent(item.domain_name) + '"><i class="bi bi-globe2"></i> DNS</a></div>';
}
else {
- item.action += '<a href="/edit/domain/' + encodeURIComponent(item.domain_name) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#dnsInfoModal" class="btn btn-xs btn-xs-half btn-info" data-bs-toggle="modal" data-domain="' + encodeURIComponent(item.domain_name) + '"><i class="bi bi-globe2"></i> DNS</a></div>';
+ item.action += '<a href="/edit/domain/' + encodeURIComponent(item.domain_name) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#dnsInfoModal" class="btn btn-sm btn-xs-lg btn-xs-half btn-info" data-bs-toggle="modal" data-domain="' + encodeURIComponent(item.domain_name) + '"><i class="bi bi-globe2"></i> DNS</a></div>';
}
if (Array.isArray(item.tags)){
@@ -598,18 +607,22 @@
defaultContent: '',
responsivePriority: 6,
render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':(0==data?'<i class="bi bi-x-lg"></i>':2==data&&'—');
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':(0==data?'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>':2==data&&'—');
}
},
{
title: lang.action,
data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
responsivePriority: 5,
defaultContent: ''
},
]
- });
+ });
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-domains', '#domain_table');
+ });
}
function draw_templates_domain_table() {
// just recalc width if instance already exists
@@ -618,17 +631,26 @@
return;
}
- $('#templates_domain_table').DataTable({
- responsive : true,
+ var table = $('#templates_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,
+ order: [[2, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-templates-domains', '#templates_domain_table');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/domain/template/all",
dataSrc: function(json){
$.each(json, function (i, item) {
- item.chkbox = '<input type="checkbox" data-id="domain_template" name="multi_select" value="' + encodeURIComponent(item.id) + '" />';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="domain_template" name="multi_select" value="' + encodeURIComponent(item.id) + '" />';
item.attributes.def_quota_for_mbox = humanFileSize(item.attributes.def_quota_for_mbox);
item.attributes.max_quota_for_mbox = humanFileSize(item.attributes.max_quota_for_mbox);
@@ -646,495 +668,18 @@
}
item.attributes.rl_value = escapeHtml(item.attributes.rl_value);
-
+
if (item.template.toLowerCase() == "default"){
item.action = '<div class="btn-group">' +
- '<a href="/edit/template/' + encodeURIComponent(item.id) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="/edit/template/' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
'</div>';
}
- else{
- item.action = '<div class="btn-group">' +
- '<a href="/edit/template/' + encodeURIComponent(item.id) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-template" data-api-url="delete/domain/template" data-item="' + encodeURIComponent(item.id) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- }
-
- if (Array.isArray(item.attributes.tags)){
- var tags = '';
- for (var i = 0; i < item.attributes.tags.length; i++)
- tags += '<span class="badge bg-primary tag-badge"><i class="bi bi-tag-fill"></i> ' + escapeHtml(item.attributes.tags[i]) + '</span>';
- item.attributes.tags = tags;
- } else {
- item.attributes.tags = '';
- }
- });
-
- return json;
- }
- },
- columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: "ID",
- data: 'id',
- responsivePriority: 2,
- defaultContent: ''
- },
- {
- title: lang.template,
- data: 'template',
- responsivePriority: 3,
- defaultContent: ''
- },
- {
- title: lang.max_aliases,
- data: 'attributes.max_num_aliases_for_domain',
- defaultContent: '',
- },
- {
- title: lang.max_mailboxes,
- data: 'attributes.max_num_mboxes_for_domain',
- defaultContent: '',
- },
- {
- title: lang.mailbox_defquota,
- data: 'attributes.def_quota_for_mbox',
- defaultContent: '',
- },
- {
- title: lang.max_quota,
- data: 'attributes.max_quota_for_mbox',
- defaultContent: '',
- },
- {
- title: lang.domain_quota_total,
- data: 'attributes.max_quota_for_domain',
- defaultContent: '',
- },
- {
- title: lang.gal,
- data: 'attributes.gal',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: lang.backup_mx,
- data: 'attributes.backupmx',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: lang.relay_all,
- data: 'attributes.relay_all_recipients',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: lang.relay_unknown,
- data: 'attributes.relay_unknown_only',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: lang.active,
- data: 'attributes.active',
- defaultContent: '',
- responsivePriority: 4,
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: 'rl_frame',
- data: 'attributes.rl_frame',
- defaultContent: '',
- class: 'none',
- },
- {
- title: 'rl_value',
- data: 'attributes.rl_value',
- defaultContent: '',
- class: 'none',
- },
- {
- title: lang.dkim_domains_selector,
- data: 'attributes.dkim_selector',
- defaultContent: '',
- class: 'none',
- },
- {
- title: lang.dkim_key_length,
- data: 'attributes.key_size',
- defaultContent: '',
- class: 'none',
- },
- {
- title: 'Tags',
- data: 'attributes.tags',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.action,
- data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md',
- responsivePriority: 6,
- defaultContent: ''
- },
- ]
- });
- }
- function draw_mailbox_table() {
- // just recalc width if instance already exists
- if ($.fn.DataTable.isDataTable('#mailbox_table') ) {
- $('#mailbox_table').DataTable().columns.adjust().responsive.recalc();
- return;
- }
-
- $('#mailbox_table').DataTable({
- responsive : true,
- processing: true,
- serverSide: false,
- language: lang_datatables,
- ajax: {
- type: "GET",
- url: "/api/v1/get/mailbox/reduced",
- dataSrc: function(json){
- $.each(json, function (i, item) {
- item.quota = item.quota_used + "/" + item.quota;
- item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
- item.last_mail_login = item.last_imap_login + '/' + item.last_pop3_login + '/' + item.last_smtp_login;
- /*
- if (!item.rl) {
- item.rl = '∞';
- } else {
- item.rl = $.map(item.rl, function(e){
- return e;
- }).join('/1');
- if (item.rl_scope === 'domain') {
- item.rl = '<i class="bi bi-arrow-return-right"></i> ' + item.rl + ' (via ' + item.domain + ')';
- }
- }
- */
- item.chkbox = '<input type="checkbox" data-id="mailbox" name="multi_select" value="' + encodeURIComponent(item.username) + '" />';
- if (item.attributes.passwd_update != '0') {
- var last_pw_change = new Date(item.attributes.passwd_update.replace(/-/g, "/"));
- item.last_pw_change = last_pw_change.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
- } else {
- item.last_pw_change = '-';
- }
- item.tls_enforce_in = '<i class="text-' + (item.attributes.tls_enforce_in == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"></i>';
- item.tls_enforce_out = '<i class="text-' + (item.attributes.tls_enforce_out == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"></i>';
- item.pop3_access = '<i class="text-' + (item.attributes.pop3_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.pop3_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
- item.imap_access = '<i class="text-' + (item.attributes.imap_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.imap_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
- item.smtp_access = '<i class="text-' + (item.attributes.smtp_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.smtp_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
- item.sieve_access = '<i class="text-' + (item.attributes.sieve_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.sieve_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
- if (item.attributes.quarantine_notification === 'never') {
- item.quarantine_notification = lang.never;
- } else if (item.attributes.quarantine_notification === 'hourly') {
- item.quarantine_notification = lang.hourly;
- } else if (item.attributes.quarantine_notification === 'daily') {
- item.quarantine_notification = lang.daily;
- } else if (item.attributes.quarantine_notification === 'weekly') {
- item.quarantine_notification = lang.weekly;
- }
- if (item.attributes.quarantine_category === 'reject') {
- item.quarantine_category = '<span class="text-danger">' + lang.q_reject + '</span>';
- } else if (item.attributes.quarantine_category === 'add_header') {
- item.quarantine_category = '<span class="text-warning">' + lang.q_add_header + '</span>';
- } else if (item.attributes.quarantine_category === 'all') {
- item.quarantine_category = lang.q_all;
- }
- if (acl_data.login_as === 1) {
-
- item.action = '<div class="btn-group">' +
- '<a href="/edit/mailbox/' + encodeURIComponent(item.username) + '" class="btn btn-sm btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-mailbox" data-api-url="delete/mailbox" data-item="' + encodeURIComponent(item.username) + '" class="btn btn-sm btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="login_as btn btn-sm btn-xs-half btn-success"><i class="bi bi-person-fill"></i> Login</a>';
- if (ALLOW_ADMIN_EMAIL_LOGIN) {
- item.action += '<a href="/sogo-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-sm btn-xs-half btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> SOGo</a>';
- }
- item.action += '</div>';
- }
else {
- item.action = '<div class="btn-group">' +
- '<a href="/edit/mailbox/' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-mailbox" data-api-url="delete/mailbox" data-item="' + encodeURIComponent(item.username) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit/template/' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-template" data-api-url="delete/domain/template" data-item="' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
}
- item.in_use = '<div class="progress">' +
- '<div class="progress-bar-mailbox progress-bar progress-bar-' + item.percent_class + '" role="progressbar" aria-valuenow="' + item.percent_in_use + '" aria-valuemin="0" aria-valuemax="100" ' +
- 'style="min-width:2em;width:' + item.percent_in_use + '%">' + item.percent_in_use + '%' + '</div></div>';
- item.username = escapeHtml(item.username);
-
- if (Array.isArray(item.tags)){
- var tags = '';
- for (var i = 0; i < item.tags.length; i++)
- tags += '<span class="badge bg-primary tag-badge"><i class="bi bi-tag-fill"></i> ' + escapeHtml(item.tags[i]) + '</span>';
- item.tags = tags;
- } else {
- item.tags = '';
- }
- });
-
- return json;
- }
- },
- columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 2
- },
- {
- title: lang.username,
- data: 'username',
- responsivePriority: 3,
- defaultContent: ''
- },
- {
- title: lang.domain_quota,
- data: 'quota',
- responsivePriority: 8,
- defaultContent: '',
- render: function (data, type) {
- data = data.split("/");
- var of_q = (data[1] == 0 ? "∞" : humanFileSize(data[1]));
- return humanFileSize(data[0]) + " / " + of_q;
- }
- },
- {
- title: lang.last_mail_login,
- data: 'last_mail_login',
- defaultContent: '',
- responsivePriority: 7,
- render: function (data, type) {
- res = data.split("/");
- return '<div class="badge bg-info mb-2">IMAP @ ' + unix_time_format(Number(res[0])) + '</div><br>' +
- '<div class="badge bg-info mb-2">POP3 @ ' + unix_time_format(Number(res[1])) + '</div><br>' +
- '<div class="badge bg-info">SMTP @ ' + unix_time_format(Number(res[2])) + '</div>';
- }
- },
- {
- title: lang.last_pw_change,
- data: 'last_pw_change',
- defaultContent: ''
- },
- {
- title: lang.in_use,
- data: 'in_use',
- defaultContent: '',
- responsivePriority: 9,
- className: 'dt-data-w100'
- },
- {
- title: lang.fname,
- data: 'name',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.domain,
- data: 'domain',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.tls_enforce_in,
- data: 'tls_enforce_in',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.tls_enforce_out,
- data: 'tls_enforce_out',
- defaultContent: '',
- className: 'none'
- },
- {
- title: 'SMTP',
- data: 'smtp_access',
- defaultContent: '',
- className: 'none'
- },
- {
- title: 'IMAP',
- data: 'imap_access',
- defaultContent: '',
- className: 'none'
- },
- {
- title: 'POP3',
- data: 'pop3_access',
- defaultContent: '',
- className: 'none'
- },
- {
- title: 'SIEVE',
- data: 'sieve_access',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.quarantine_notification,
- data: 'quarantine_notification',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.quarantine_category,
- data: 'quarantine_category',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.msg_num,
- data: 'messages',
- defaultContent: '',
- responsivePriority: 5
- },
- {
- title: lang.created_on,
- data: 'created',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.last_modified,
- data: 'modified',
- defaultContent: '',
- className: 'none'
- },
- {
- title: 'Tags',
- data: 'tags',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- responsivePriority: 4,
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':(0==data?'<i class="bi bi-x-lg"></i>':2==data&&'—');
- }
- },
- {
- title: lang.action,
- data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md',
- responsivePriority: 6,
- defaultContent: ''
- },
- ]
- });
- }
- function draw_templates_mbox_table() {
- // just recalc width if instance already exists
- if ($.fn.DataTable.isDataTable('#templates_mbox_table') ) {
- $('#templates_mbox_table').DataTable().columns.adjust().responsive.recalc();
- return;
- }
-
- $('#templates_mbox_table').DataTable({
- responsive : true,
- processing: true,
- serverSide: false,
- language: lang_datatables,
- ajax: {
- type: "GET",
- url: "/api/v1/get/mailbox/template/all",
- dataSrc: function(json){
- $.each(json, function (i, item) {
- item.chkbox = '<input type="checkbox" data-id="mailbox_template" name="multi_select" value="' + encodeURIComponent(item.id) + '" />';
-
- item.template = escapeHtml(item.template);
- if (item.attributes.rl_frame === "s"){
- item.attributes.rl_frame = lang_rl.second;
- } else if (item.attributes.rl_frame === "m"){
- item.attributes.rl_frame = lang_rl.minute;
- } else if (item.attributes.rl_frame === "h"){
- item.attributes.rl_frame = lang_rl.hour;
- } else if (item.attributes.rl_frame === "d"){
- item.attributes.rl_frame = lang_rl.day;
- }
- item.attributes.rl_value = escapeHtml(item.attributes.rl_value);
-
- item.attributes.quota = humanFileSize(item.attributes.quota);
-
- item.attributes.tls_enforce_in = '<i class="text-' + (item.attributes.tls_enforce_in == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"></i>';
- item.attributes.tls_enforce_out = '<i class="text-' + (item.attributes.tls_enforce_out == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"></i>';
- item.attributes.pop3_access = '<i class="text-' + (item.attributes.pop3_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.pop3_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
- item.attributes.imap_access = '<i class="text-' + (item.attributes.imap_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.imap_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
- item.attributes.smtp_access = '<i class="text-' + (item.attributes.smtp_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.smtp_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
- item.attributes.sieve_access = '<i class="text-' + (item.attributes.sieve_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.sieve_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
- item.attributes.sogo_access = '<i class="text-' + (item.attributes.sogo_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.sogo_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
- if (item.attributes.quarantine_notification === 'never') {
- item.attributes.quarantine_notification = lang.never;
- } else if (item.attributes.quarantine_notification === 'hourly') {
- item.attributes.quarantine_notification = lang.hourly;
- } else if (item.attributes.quarantine_notification === 'daily') {
- item.attributes.quarantine_notification = lang.daily;
- } else if (item.attributes.quarantine_notification === 'weekly') {
- item.attributes.quarantine_notification = lang.weekly;
- }
- if (item.attributes.quarantine_category === 'reject') {
- item.attributes.quarantine_category = '<span class="text-danger">' + lang.q_reject + '</span>';
- } else if (item.attributes.quarantine_category === 'add_header') {
- item.attributes.quarantine_category = '<span class="text-warning">' + lang.q_add_header + '</span>';
- } else if (item.attributes.quarantine_category === 'all') {
- item.attributes.quarantine_category = lang.q_all;
- }
-
-
- if (item.template.toLowerCase() == "default"){
- item.action = '<div class="btn-group">' +
- '<a href="/edit/template/' + encodeURIComponent(item.id) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '</div>';
- }
- else {
- item.action = '<div class="btn-group">' +
- '<a href="/edit/template/' + encodeURIComponent(item.id) + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-template" data-api-url="delete/mailbox/template" data-item="' + encodeURIComponent(item.id) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- }
if (Array.isArray(item.attributes.tags)){
var tags = '';
@@ -1178,12 +723,532 @@
data: 'template',
responsivePriority: 3,
defaultContent: ''
- },
+ },
+ {
+ title: lang.max_aliases,
+ data: 'attributes.max_num_aliases_for_domain',
+ defaultContent: '',
+ },
+ {
+ title: lang.max_mailboxes,
+ data: 'attributes.max_num_mboxes_for_domain',
+ defaultContent: '',
+ },
+ {
+ title: lang.mailbox_defquota,
+ data: 'attributes.def_quota_for_mbox',
+ defaultContent: '',
+ },
+ {
+ title: lang.max_quota,
+ data: 'attributes.max_quota_for_mbox',
+ defaultContent: '',
+ },
+ {
+ title: lang.domain_quota_total,
+ data: 'attributes.max_quota_for_domain',
+ defaultContent: '',
+ },
+ {
+ title: lang.gal,
+ data: 'attributes.gal',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.backup_mx,
+ data: 'attributes.backupmx',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.relay_all,
+ data: 'attributes.relay_all_recipients',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.relay_unknown,
+ data: 'attributes.relay_unknown_only',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.active,
+ data: 'attributes.active',
+ defaultContent: '',
+ responsivePriority: 4,
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: 'rl_frame',
+ data: 'attributes.rl_frame',
+ defaultContent: '',
+ class: 'none',
+ },
+ {
+ title: 'rl_value',
+ data: 'attributes.rl_value',
+ defaultContent: '',
+ class: 'none',
+ },
+ {
+ title: lang.dkim_domains_selector,
+ data: 'attributes.dkim_selector',
+ defaultContent: '',
+ class: 'none',
+ },
+ {
+ title: lang.dkim_key_length,
+ data: 'attributes.key_size',
+ defaultContent: '',
+ class: 'none',
+ },
+ {
+ title: 'Tags',
+ data: 'attributes.tags',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
+ responsivePriority: 6,
+ defaultContent: ''
+ },
+ ]
+ });
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-templates-domains', '#templates_domain_table');
+ });
+ }
+ function draw_mailbox_table() {
+ // just recalc width if instance already exists
+ if ($.fn.DataTable.isDataTable('#mailbox_table') ) {
+ $('#mailbox_table').DataTable().columns.adjust().responsive.recalc();
+ return;
+ }
+
+ var table = $('#mailbox_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,
+ initComplete: function(settings, json){
+ hideTableExpandCollapseBtn('#tab-mailboxes', '#mailbox_table');
+ filterByDomain(json, 8, table);
+ },
+ ajax: {
+ type: "GET",
+ url: "/api/v1/get/mailbox/reduced",
+ dataSrc: function(json){
+ $.each(json, function (i, item) {
+ item.quota = {
+ sortBy: item.quota_used,
+ value: item.quota
+ }
+ item.quota.value = (item.quota.value == 0 ? "∞" : humanFileSize(item.quota.value));
+ item.quota.value = humanFileSize(item.quota_used) + "/" + item.quota.value;
+
+ item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
+ item.last_mail_login = item.last_imap_login + '/' + item.last_pop3_login + '/' + item.last_smtp_login;
+ /*
+ if (!item.rl) {
+ item.rl = '∞';
+ } else {
+ item.rl = $.map(item.rl, function(e){
+ return e;
+ }).join('/1');
+ if (item.rl_scope === 'domain') {
+ item.rl = '<i class="bi bi-arrow-return-right"></i> ' + item.rl + ' (via ' + item.domain + ')';
+ }
+ }
+ */
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="mailbox" name="multi_select" value="' + encodeURIComponent(item.username) + '" />';
+ if (item.attributes.passwd_update != '0') {
+ var last_pw_change = new Date(item.attributes.passwd_update.replace(/-/g, "/"));
+ item.last_pw_change = last_pw_change.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
+ } else {
+ item.last_pw_change = '-';
+ }
+ item.tls_enforce_in = '<i class="text-' + (item.attributes.tls_enforce_in == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"></i>';
+ item.tls_enforce_out = '<i class="text-' + (item.attributes.tls_enforce_out == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"></i>';
+ item.pop3_access = '<i class="text-' + (item.attributes.pop3_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.pop3_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
+ item.imap_access = '<i class="text-' + (item.attributes.imap_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.imap_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
+ item.smtp_access = '<i class="text-' + (item.attributes.smtp_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.smtp_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
+ item.sieve_access = '<i class="text-' + (item.attributes.sieve_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.sieve_access == 1 ? 'check-lg' : 'x-lg') + '"></i>';
+ if (item.attributes.quarantine_notification === 'never') {
+ item.quarantine_notification = lang.never;
+ } else if (item.attributes.quarantine_notification === 'hourly') {
+ item.quarantine_notification = lang.hourly;
+ } else if (item.attributes.quarantine_notification === 'daily') {
+ item.quarantine_notification = lang.daily;
+ } else if (item.attributes.quarantine_notification === 'weekly') {
+ item.quarantine_notification = lang.weekly;
+ }
+ if (item.attributes.quarantine_category === 'reject') {
+ item.quarantine_category = '<span class="text-danger">' + lang.q_reject + '</span>';
+ } else if (item.attributes.quarantine_category === 'add_header') {
+ item.quarantine_category = '<span class="text-warning">' + lang.q_add_header + '</span>';
+ } else if (item.attributes.quarantine_category === 'all') {
+ item.quarantine_category = lang.q_all;
+ }
+ if (acl_data.login_as === 1) {
+
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit/mailbox/' + encodeURIComponent(item.username) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-mailbox" data-api-url="delete/mailbox" data-item="' + encodeURIComponent(item.username) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="/index.php?duallogin=' + encodeURIComponent(item.username) + '" class="login_as btn btn-sm btn-xs-lg btn-xs-half btn-success"><i class="bi bi-person-fill"></i> Login</a>';
+ if (ALLOW_ADMIN_EMAIL_LOGIN) {
+ item.action += '<a href="/sogo-auth.php?login=' + encodeURIComponent(item.username) + '" class="login_as btn btn-sm btn-xs-lg btn-xs-half btn-primary" target="_blank"><i class="bi bi-envelope-fill"></i> SOGo</a>';
+ }
+ item.action += '</div>';
+ }
+ else {
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit/mailbox/' + encodeURIComponent(item.username) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-mailbox" data-api-url="delete/mailbox" data-item="' + encodeURIComponent(item.username) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ }
+ item.in_use = {
+ sortBy: item.percent_in_use,
+ value: '<div class="progress">' +
+ '<div class="progress-bar-mailbox progress-bar progress-bar-' + item.percent_class + '" role="progressbar" aria-valuenow="' + item.percent_in_use + '" aria-valuemin="0" aria-valuemax="100" ' +
+ 'style="min-width:2em;width:' + item.percent_in_use + '%">' + item.percent_in_use + '%' + '</div></div>'
+ };
+ item.username = escapeHtml(item.username);
+
+ if (Array.isArray(item.tags)){
+ var tags = '';
+ for (var i = 0; i < item.tags.length; i++)
+ tags += '<span class="badge bg-primary tag-badge"><i class="bi bi-tag-fill"></i> ' + escapeHtml(item.tags[i]) + '</span>';
+ item.tags = tags;
+ } else {
+ item.tags = '';
+ }
+ });
+
+ return json;
+ }
+ },
+ columns: [
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 2
+ },
+ {
+ title: lang.username,
+ data: 'username',
+ responsivePriority: 3,
+ defaultContent: ''
+ },
+ {
+ title: lang.domain_quota,
+ data: 'quota.value',
+ responsivePriority: 8,
+ defaultContent: '',
+ orderData: 23
+ },
+ {
+ title: lang.last_mail_login,
+ data: 'last_mail_login',
+ defaultContent: '',
+ responsivePriority: 7,
+ render: function (data, type) {
+ res = data.split("/");
+ return '<div class="badge bg-info mb-2">IMAP @ ' + unix_time_format(Number(res[0])) + '</div><br>' +
+ '<div class="badge bg-info mb-2">POP3 @ ' + unix_time_format(Number(res[1])) + '</div><br>' +
+ '<div class="badge bg-info">SMTP @ ' + unix_time_format(Number(res[2])) + '</div>';
+ }
+ },
+ {
+ title: lang.last_pw_change,
+ data: 'last_pw_change',
+ defaultContent: ''
+ },
+ {
+ title: lang.in_use,
+ data: 'in_use.value',
+ defaultContent: '',
+ responsivePriority: 9,
+ className: 'dt-data-w100',
+ orderData: 24
+ },
+ {
+ title: lang.fname,
+ data: 'name',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.domain,
+ data: 'domain',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.tls_enforce_in,
+ data: 'tls_enforce_in',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.tls_enforce_out,
+ data: 'tls_enforce_out',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: 'SMTP',
+ data: 'smtp_access',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: 'IMAP',
+ data: 'imap_access',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: 'POP3',
+ data: 'pop3_access',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: 'SIEVE',
+ data: 'sieve_access',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.quarantine_notification,
+ data: 'quarantine_notification',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.quarantine_category,
+ data: 'quarantine_category',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.msg_num,
+ data: 'messages',
+ defaultContent: '',
+ responsivePriority: 5
+ },
+ {
+ title: lang.created_on,
+ data: 'created',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.last_modified,
+ data: 'modified',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: 'Tags',
+ data: 'tags',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ responsivePriority: 4,
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':(0==data?'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>':2==data&&'—');
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
+ responsivePriority: 6,
+ defaultContent: ''
+ },
+ {
+ title: "",
+ data: 'quota.sortBy',
+ defaultContent: '',
+ className: "d-none"
+ },
+ {
+ title: "",
+ data: 'in_use.sortBy',
+ defaultContent: '',
+ className: "d-none"
+ },
+ ]
+ });
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-mailboxes', '#mailbox_table');
+ });
+ }
+ function draw_templates_mbox_table() {
+ // just recalc width if instance already exists
+ if ($.fn.DataTable.isDataTable('#templates_mbox_table') ) {
+ $('#templates_mbox_table').DataTable().columns.adjust().responsive.recalc();
+ return;
+ }
+
+ var table = $('#templates_mbox_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,
+ order: [[2, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-templates-mbox', '#templates_mbox_table');
+ },
+ ajax: {
+ type: "GET",
+ url: "/api/v1/get/mailbox/template/all",
+ dataSrc: function(json){
+ $.each(json, function (i, item) {
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="mailbox_template" name="multi_select" value="' + encodeURIComponent(item.id) + '" />';
+
+ item.template = escapeHtml(item.template);
+ if (item.attributes.rl_frame === "s"){
+ item.attributes.rl_frame = lang_rl.second;
+ } else if (item.attributes.rl_frame === "m"){
+ item.attributes.rl_frame = lang_rl.minute;
+ } else if (item.attributes.rl_frame === "h"){
+ item.attributes.rl_frame = lang_rl.hour;
+ } else if (item.attributes.rl_frame === "d"){
+ item.attributes.rl_frame = lang_rl.day;
+ }
+ item.attributes.rl_value = escapeHtml(item.attributes.rl_value);
+
+ item.attributes.quota = humanFileSize(item.attributes.quota);
+
+ item.attributes.tls_enforce_in = '<i class="text-' + (item.attributes.tls_enforce_in == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"><span class="sorting-value">' + (item.attributes.tls_enforce_in == 1 ? '1' : '0') + '</span></i>';
+ item.attributes.tls_enforce_out = '<i class="text-' + (item.attributes.tls_enforce_out == 1 ? 'success bi bi-lock-fill' : 'danger bi bi-unlock-fill') + '"><span class="sorting-value">' + (item.attributes.tls_enforce_out == 1 ? '1' : '0') + '</span></i>';
+ item.attributes.pop3_access = '<i class="text-' + (item.attributes.pop3_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.pop3_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.pop3_access == 1 ? '1' : '0') + '</span></i>';
+ item.attributes.imap_access = '<i class="text-' + (item.attributes.imap_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.imap_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.imap_access == 1 ? '1' : '0') + '</span></i>';
+ item.attributes.smtp_access = '<i class="text-' + (item.attributes.smtp_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.smtp_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.smtp_access == 1 ? '1' : '0') + '</span></i>';
+ item.attributes.sieve_access = '<i class="text-' + (item.attributes.sieve_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.sieve_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.sieve_access == 1 ? '1' : '0') + '</span></i>';
+ item.attributes.sogo_access = '<i class="text-' + (item.attributes.sogo_access == 1 ? 'success' : 'danger') + ' bi bi-' + (item.attributes.sogo_access == 1 ? 'check-lg' : 'x-lg') + '"><span class="sorting-value">' + (item.attributes.sogo_access == 1 ? '1' : '0') + '</span></i>';
+ if (item.attributes.quarantine_notification === 'never') {
+ item.attributes.quarantine_notification = lang.never;
+ } else if (item.attributes.quarantine_notification === 'hourly') {
+ item.attributes.quarantine_notification = lang.hourly;
+ } else if (item.attributes.quarantine_notification === 'daily') {
+ item.attributes.quarantine_notification = lang.daily;
+ } else if (item.attributes.quarantine_notification === 'weekly') {
+ item.attributes.quarantine_notification = lang.weekly;
+ }
+ if (item.attributes.quarantine_category === 'reject') {
+ item.attributes.quarantine_category = '<span class="text-danger">' + lang.q_reject + '</span>';
+ } else if (item.attributes.quarantine_category === 'add_header') {
+ item.attributes.quarantine_category = '<span class="text-warning">' + lang.q_add_header + '</span>';
+ } else if (item.attributes.quarantine_category === 'all') {
+ item.attributes.quarantine_category = lang.q_all;
+ }
+
+ if (item.template.toLowerCase() == "default"){
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit/template/' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '</div>';
+ }
+ else {
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit/template/' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-template" data-api-url="delete/mailbox/template" data-item="' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ }
+
+ if (Array.isArray(item.attributes.tags)){
+ var tags = '';
+ for (var i = 0; i < item.attributes.tags.length; i++)
+ tags += '<span class="badge bg-primary tag-badge"><i class="bi bi-tag-fill"></i> ' + escapeHtml(item.attributes.tags[i]) + '</span>';
+ item.attributes.tags = tags;
+ } else {
+ item.attributes.tags = '';
+ }
+ });
+
+ return json;
+ }
+ },
+ columns: [
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: "ID",
+ data: 'id',
+ responsivePriority: 2,
+ defaultContent: ''
+ },
+ {
+ title: lang.template,
+ data: 'template',
+ responsivePriority: 3,
+ defaultContent: ''
+ },
{
title: lang.domain_quota,
data: 'attributes.quota',
defaultContent: '',
- },
+ },
{
title: lang.tls_enforce_in,
data: 'attributes.tls_enforce_in',
@@ -1230,7 +1295,7 @@
data: 'attributes.quarantine_category',
defaultContent: '',
className: 'none'
- },
+ },
{
title: lang.force_pw_update,
data: 'attributes.force_pw_update',
@@ -1239,43 +1304,47 @@
render: function (data, type) {
return 1==data?'<i class="bi bi-check-lg"></i>':'<i class="bi bi-x-lg"></i>';
}
- },
+ },
{
title: "rl_frame",
data: 'attributes.rl_frame',
defaultContent: '',
class: 'none',
- },
+ },
{
title: 'rl_value',
data: 'attributes.rl_value',
defaultContent: '',
class: 'none',
- },
+ },
{
title: 'Tags',
data: 'attributes.tags',
defaultContent: '',
className: 'none'
- },
+ },
{
title: lang.active,
data: 'attributes.active',
defaultContent: '',
responsivePriority: 4,
render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':(0==data?'<i class="bi bi-x-lg"></i>':2==data&&'—');
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':(0==data?'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>':2==data&&'—');
}
- },
+ },
{
title: lang.action,
data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
responsivePriority: 6,
defaultContent: ''
},
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-templates-mbox', '#templates_mbox_table');
+ });
}
function draw_resource_table() {
// just recalc width if instance already exists
@@ -1284,10 +1353,20 @@
return;
}
- $('#resource_table').DataTable({
+ var table = $('#resource_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,
+ initComplete: function(settings, json){
+ hideTableExpandCollapseBtn('#tab-resources', '#resource_table');
+ filterByDomain(json, 5, table);
+ },
ajax: {
type: "GET",
url: "/api/v1/get/resource/all",
@@ -1301,10 +1380,10 @@
item.multiple_bookings = '<span id="active-script" class="badge fs-6 bg-danger">' + lang.booking_custom_short + ' (' + item.multiple_bookings + ')</span>';
}
item.action = '<div class="btn-group">' +
- '<a href="/edit/resource/' + encodeURIComponent(item.name) + '" class="btn btn-sm btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-resource" data-api-url="delete/resource" data-item="' + item.name + '" class="btn btn-sm btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="/edit/resource/' + encodeURIComponent(item.name) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-resource" data-api-url="delete/resource" data-item="' + item.name + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
- item.chkbox = '<input type="checkbox" data-id="resource" name="multi_select" value="' + encodeURIComponent(item.name) + '" />';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="resource" name="multi_select" value="' + encodeURIComponent(item.name) + '" />';
item.name = escapeHtml(item.name);
item.description = escapeHtml(item.description);
});
@@ -1313,94 +1392,105 @@
}
},
columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 2
- },
- {
- title: lang.description,
- data: 'description',
- responsivePriority: 3,
- defaultContent: ''
- },
- {
- title: lang.alias,
- data: 'name',
- defaultContent: ''
- },
- {
- title: lang.kind,
- data: 'kind',
- defaultContent: ''
- },
- {
- title: lang.domain,
- data: 'domain',
- responsivePriority: 4,
- defaultContent: ''
- },
- {
- title: lang.multiple_bookings,
- data: 'multiple_bookings',
- defaultContent: ''
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':(0==data?'<i class="bi bi-x-lg"></i>':2==data&&'—');
- }
- },
- {
- title: lang.action,
- data: 'action',
- responsivePriority: 5,
- defaultContent: '',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-body-right'
- },
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 2
+ },
+ {
+ title: lang.description,
+ data: 'description',
+ responsivePriority: 3,
+ defaultContent: ''
+ },
+ {
+ title: lang.alias,
+ data: 'name',
+ defaultContent: ''
+ },
+ {
+ title: lang.kind,
+ data: 'kind',
+ defaultContent: ''
+ },
+ {
+ title: lang.domain,
+ data: 'domain',
+ responsivePriority: 4,
+ defaultContent: ''
+ },
+ {
+ title: lang.multiple_bookings,
+ data: 'multiple_bookings',
+ defaultContent: ''
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':(0==data?'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>':2==data&&'—');
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ responsivePriority: 5,
+ defaultContent: '',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right'
+ },
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-resources', '#resource_table');
+ });
}
function draw_bcc_table() {
$.get("/api/v1/get/bcc-destination-options", function(data){
+ var optgroup = "";
// Domains
- var optgroup = "<optgroup label='" + lang.domains + "'>";
- $.each(data.domains, function(index, domain){
- optgroup += "<option value='" + domain + "'>" + domain + "</option>"
- });
- optgroup += "</optgroup>"
- $('#bcc-local-dest').append(optgroup);
+ if (data.domains && data.domains.length > 0) {
+ optgroup = "<optgroup label='" + lang.domains + "'>";
+ $.each(data.domains, function(index, domain){
+ optgroup += "<option value='" + domain + "'>" + domain + "</option>";
+ });
+ optgroup += "</optgroup>";
+ $('#bcc-local-dest').append(optgroup);
+ }
// Alias domains
- var optgroup = "<optgroup label='" + lang.domain_aliases + "'>";
- $.each(data.alias_domains, function(index, alias_domain){
- optgroup += "<option value='" + alias_domain + "'>" + alias_domain + "</option>"
- });
- optgroup += "</optgroup>"
- $('#bcc-local-dest').append(optgroup);
- // Mailboxes and aliases
- $.each(data.mailboxes, function(mailbox, aliases){
- var optgroup = "<optgroup label='" + mailbox + "'>";
- $.each(aliases, function(index, alias){
- optgroup += "<option value='" + alias + "'>" + alias + "</option>"
+ if (data.alias_domains && data.alias_domains.length > 0) {
+ optgroup = "<optgroup label='" + lang.domain_aliases + "'>";
+ $.each(data.alias_domains, function(index, alias_domain){
+ optgroup += "<option value='" + alias_domain + "'>" + alias_domain + "</option>";
});
optgroup += "</optgroup>"
$('#bcc-local-dest').append(optgroup);
- });
- // Finish
+ }
+ // Mailboxes and aliases
+ if (data.mailboxes && Object.keys(data.mailboxes).length > 0) {
+ $.each(data.mailboxes, function(mailbox, aliases){
+ optgroup = "<optgroup label='" + mailbox + "'>";
+ $.each(aliases, function(index, alias){
+ optgroup += "<option value='" + alias + "'>" + alias + "</option>";
+ });
+ optgroup += "</optgroup>";
+ $('#bcc-local-dest').append(optgroup);
+ });
+ }
+ // Recreate picker
$('#bcc-local-dest').selectpicker('refresh');
});
@@ -1409,21 +1499,32 @@
$('#bcc_table').DataTable().columns.adjust().responsive.recalc();
return;
}
-
- $('#bcc_table').DataTable({
+
+ var table = $('#bcc_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,
+ order: [[2, 'desc']],
+ initComplete: function(settings, json){
+ hideTableExpandCollapseBtn('#collapse-tab-bcc', '#bcc_table');
+ filterByDomain(json, 6, table);
+ },
ajax: {
type: "GET",
url: "/api/v1/get/bcc/all",
dataSrc: function(json){
$.each(json, function (i, item) {
item.action = '<div class="btn-group">' +
- '<a href="/edit/bcc/' + item.id + '" class="btn btn-sm btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-bcc" data-api-url="delete/bcc" data-item="' + item.id + '" class="btn btn-sm btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="/edit/bcc/' + item.id + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-bcc" data-api-url="delete/bcc" data-item="' + item.id + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
- item.chkbox = '<input type="checkbox" data-id="bcc" name="multi_select" value="' + item.id + '" />';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="bcc" name="multi_select" value="' + item.id + '" />';
item.local_dest = escapeHtml(item.local_dest);
item.bcc_dest = escapeHtml(item.bcc_dest);
if (item.type == 'sender') {
@@ -1437,67 +1538,71 @@
}
},
columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 2
- },
- {
- title: 'ID',
- data: 'id',
- responsivePriority: 3,
- defaultContent: ''
- },
- {
- title: lang.bcc_type,
- data: 'type',
- defaultContent: ''
- },
- {
- title: lang.bcc_local_dest,
- data: 'local_dest',
- defaultContent: ''
- },
- {
- title: lang.bcc_destinations,
- data: 'bcc_dest',
- defaultContent: ''
- },
- {
- title: lang.domain,
- data: 'domain',
- responsivePriority: 4,
- defaultContent: ''
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':(0==data?'<i class="bi bi-x-lg"></i>':2==data&&'—');
- }
- },
- {
- title: lang.action,
- data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-body-right',
- responsivePriority: 5,
- defaultContent: ''
- },
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 2
+ },
+ {
+ title: 'ID',
+ data: 'id',
+ responsivePriority: 3,
+ defaultContent: ''
+ },
+ {
+ title: lang.bcc_type,
+ data: 'type',
+ defaultContent: ''
+ },
+ {
+ title: lang.bcc_local_dest,
+ data: 'local_dest',
+ defaultContent: ''
+ },
+ {
+ title: lang.bcc_destinations,
+ data: 'bcc_dest',
+ defaultContent: ''
+ },
+ {
+ title: lang.domain,
+ data: 'domain',
+ responsivePriority: 4,
+ defaultContent: ''
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':(0==data?'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>':2==data&&'—');
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
+ responsivePriority: 5,
+ defaultContent: ''
+ },
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#collapse-tab-bcc', '#bcc_table');
+ });
}
function draw_recipient_map_table() {
// just recalc width if instance already exists
@@ -1506,81 +1611,95 @@
return;
}
- $('#recipient_map_table').DataTable({
+ var table = $('#recipient_map_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,
+ order: [[2, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#collapse-tab-bcc-filters', '#recipient_map_table');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/recipient_map/all",
dataSrc: function(json){
if (role !== "admin") return null;
-
+
$.each(json, function (i, item) {
item.recipient_map_old = escapeHtml(item.recipient_map_old);
item.recipient_map_new = escapeHtml(item.recipient_map_new);
item.action = '<div class="btn-group">' +
- '<a href="/edit/recipient_map/' + item.id + '" class="btn btn-sm btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-recipient_map" data-api-url="delete/recipient_map" data-item="' + item.id + '" class="btn btn-sm btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="/edit/recipient_map/' + item.id + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-recipient_map" data-api-url="delete/recipient_map" data-item="' + item.id + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
- item.chkbox = '<input type="checkbox" data-id="recipient_map" name="multi_select" value="' + item.id + '" />';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="recipient_map" name="multi_select" value="' + item.id + '" />';
});
return json;
}
},
columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 2
- },
- {
- title: 'ID',
- data: 'id',
- responsivePriority: 3,
- defaultContent: ''
- },
- {
- title: lang.recipient_map_old,
- data: 'recipient_map_old',
- defaultContent: ''
- },
- {
- title: lang.recipient_map_new,
- data: 'recipient_map_new',
- defaultContent: '',
- responsivePriority: 4
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: lang.action,
- data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-body-right',
- responsivePriority: 5,
- defaultContent: ''
- },
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 2
+ },
+ {
+ title: 'ID',
+ data: 'id',
+ responsivePriority: 3,
+ defaultContent: ''
+ },
+ {
+ title: lang.recipient_map_old,
+ data: 'recipient_map_old',
+ defaultContent: ''
+ },
+ {
+ title: lang.recipient_map_new,
+ data: 'recipient_map_new',
+ defaultContent: '',
+ responsivePriority: 4
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
+ responsivePriority: 5,
+ defaultContent: ''
+ },
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#collapse-tab-bcc-filters', '#recipient_map_table');
+ });
}
function draw_tls_policy_table() {
// just recalc width if instance already exists
@@ -1589,16 +1708,26 @@
return;
}
- $('#tls_policy_table').DataTable({
+ var table = $('#tls_policy_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,
+ order: [[2, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-tls-policy', '#tls_policy_table');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/tls-policy-map/all",
dataSrc: function(json){
if (role !== "admin") return null;
-
+
$.each(json, function (i, item) {
item.dest = escapeHtml(item.dest);
item.policy = '<b>' + escapeHtml(item.policy) + '</b>';
@@ -1608,72 +1737,76 @@
item.parameters = '<code>' + escapeHtml(item.parameters) + '</code>';
}
item.action = '<div class="btn-group">' +
- '<a href="/edit/tls_policy_map/' + item.id + '" class="btn btn-sm btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-tls-policy-map" data-api-url="delete/tls-policy-map" data-item="' + item.id + '" class="btn btn-sm btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="/edit/tls_policy_map/' + item.id + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-tls-policy-map" data-api-url="delete/tls-policy-map" data-item="' + item.id + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
- item.chkbox = '<input type="checkbox" data-id="tls-policy-map" name="multi_select" value="' + item.id + '" />';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="tls-policy-map" name="multi_select" value="' + item.id + '" />';
});
return json;
}
},
columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 2
- },
- {
- title: 'ID',
- data: 'id',
- responsivePriority: 3,
- defaultContent: ''
- },
- {
- title: lang.tls_map_dest,
- data: 'dest',
- defaultContent: '',
- responsivePriority: 4
- },
- {
- title: lang.tls_map_policy,
- data: 'policy',
- defaultContent: ''
- },
- {
- title: lang.tls_map_parameters,
- data: 'parameters',
- defaultContent: ''
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: lang.action,
- data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-body-right',
- responsivePriority: 5,
- defaultContent: ''
- },
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 2
+ },
+ {
+ title: 'ID',
+ data: 'id',
+ responsivePriority: 3,
+ defaultContent: ''
+ },
+ {
+ title: lang.tls_map_dest,
+ data: 'dest',
+ defaultContent: '',
+ responsivePriority: 4
+ },
+ {
+ title: lang.tls_map_policy,
+ data: 'policy',
+ defaultContent: ''
+ },
+ {
+ title: lang.tls_map_parameters,
+ data: 'parameters',
+ defaultContent: ''
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
+ responsivePriority: 5,
+ defaultContent: ''
+ },
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-tls-policy', '#tls_policy_table');
+ });
}
function draw_alias_table() {
// just recalc width if instance already exists
@@ -1682,20 +1815,31 @@
return;
}
- $('#alias_table').DataTable({
+ var table = $('#alias_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,
+ order: [[2, 'desc']],
+ initComplete: function(settings, json){
+ hideTableExpandCollapseBtn('#tab-mbox-aliases', '#alias_table');
+ filterByDomain(json, 5, table);
+ },
ajax: {
type: "GET",
url: "/api/v1/get/alias/all",
dataSrc: function(json){
$.each(json, function (i, item) {
item.action = '<div class="btn-group">' +
- '<a href="/edit/alias/' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-alias" data-api-url="delete/alias" data-item="' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="/edit/alias/' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-alias" data-api-url="delete/alias" data-item="' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
- item.chkbox = '<input type="checkbox" data-id="alias" name="multi_select" value="' + encodeURIComponent(item.id) + '" />';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="alias" name="multi_select" value="' + encodeURIComponent(item.id) + '" />';
item.goto = escapeHtml(item.goto.replace(/,/g, " "));
if (item.public_comment !== null) {
item.public_comment = escapeHtml(item.public_comment);
@@ -1733,87 +1877,95 @@
}
},
columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 2
- },
- {
- title: 'ID',
- data: 'id',
- responsivePriority: 3,
- defaultContent: ''
- },
- {
- title: lang.alias,
- data: 'address',
- responsivePriority: 4,
- defaultContent: ''
- },
- {
- title: lang.target_address,
- data: 'goto',
- defaultContent: ''
- },
- {
- title: lang.domain,
- data: 'domain',
- defaultContent: '',
- responsivePriority: 5,
- },
- {
- title: lang.bcc_destinations,
- data: 'bcc_dest',
- defaultContent: ''
- },
- {
- title: lang.sogo_visible,
- data: 'sogo_visible',
- defaultContent: '',
- render: function(data, type){
- return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: lang.public_comment,
- data: 'public_comment',
- defaultContent: ''
- },
- {
- title: lang.private_comment,
- data: 'private_comment',
- defaultContent: ''
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- responsivePriority: 6,
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: lang.action,
- data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-body-right',
- responsivePriority: 5,
- defaultContent: ''
- },
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 2
+ },
+ {
+ title: 'ID',
+ data: 'id',
+ responsivePriority: 3,
+ defaultContent: ''
+ },
+ {
+ title: lang.alias,
+ data: 'address',
+ responsivePriority: 4,
+ defaultContent: ''
+ },
+ {
+ title: lang.target_address,
+ data: 'goto',
+ defaultContent: ''
+ },
+ {
+ title: lang.domain,
+ data: 'domain',
+ defaultContent: '',
+ responsivePriority: 5,
+ },
+ {
+ title: lang.bcc_destinations,
+ data: 'bcc_dest',
+ defaultContent: ''
+ },
+ {
+ title: lang.sogo_visible,
+ data: 'sogo_visible',
+ defaultContent: '',
+ render: function(data, type){
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.public_comment,
+ data: 'public_comment',
+ defaultContent: ''
+ },
+ {
+ title: lang.private_comment,
+ data: 'private_comment',
+ defaultContent: ''
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ responsivePriority: 6,
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
+ responsivePriority: 5,
+ defaultContent: ''
+ },
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-mbox-aliases', '#alias_table');
+ });
+
+ table.on( 'draw', function (){
+ $('#alias_table [data-bs-toggle="tooltip"]').tooltip();
+ });
}
function draw_aliasdomain_table() {
// just recalc width if instance already exists
@@ -1822,10 +1974,19 @@
return;
}
- $('#aliasdomain_table').DataTable({
+ var table = $('#aliasdomain_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,
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-domain-aliases', '#aliasdomain_table');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/alias-domain/all",
@@ -1834,11 +1995,11 @@
item.alias_domain = escapeHtml(item.alias_domain);
item.action = '<div class="btn-group">' +
- '<a href="/edit/aliasdomain/' + encodeURIComponent(item.alias_domain) + '" class="btn btn-sm btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-alias-domain" data-api-url="delete/alias-domain" data-item="' + encodeURIComponent(item.alias_domain) + '" class="btn btn-sm btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '<a href="#dnsInfoModal" class="btn btn-sm btn-xs-third btn-info" data-bs-toggle="modal" data-domain="' + encodeURIComponent(item.alias_domain) + '"><i class="bi bi-globe2"></i> DNS</a></div>' +
+ '<a href="/edit/aliasdomain/' + encodeURIComponent(item.alias_domain) + '" class="btn btn-sm btn-xs-lg btn-xs-third btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-alias-domain" data-api-url="delete/alias-domain" data-item="' + encodeURIComponent(item.alias_domain) + '" class="btn btn-sm btn-xs-lg btn-xs-third btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="#dnsInfoModal" class="btn btn-sm btn-xs-lg btn-xs-third btn-info" data-bs-toggle="modal" data-domain="' + encodeURIComponent(item.alias_domain) + '"><i class="bi bi-globe2"></i> DNS</a></div>' +
'</div>';
- item.chkbox = '<input type="checkbox" data-id="alias-domain" name="multi_select" value="' + encodeURIComponent(item.alias_domain) + '" />';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="alias-domain" name="multi_select" value="' + encodeURIComponent(item.alias_domain) + '" />';
if(item.parent_is_backupmx == '1') {
item.target_domain = '<span><a href="/edit/domain/' + item.target_domain + '">' + item.target_domain + '</a> <div class="badge fs-6 bg-warning">' + lang.alias_domain_backupmx + '</div></span>';
} else {
@@ -1850,52 +2011,56 @@
}
},
columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 2
- },
- {
- title: lang.alias,
- data: 'alias_domain',
- responsivePriority: 3,
- defaultContent: ''
- },
- {
- title: lang.target_domain,
- data: 'target_domain',
- responsivePriority: 4,
- defaultContent: ''
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: lang.action,
- data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-body-right',
- responsivePriority: 5,
- defaultContent: ''
- },
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 2
+ },
+ {
+ title: lang.alias,
+ data: 'alias_domain',
+ responsivePriority: 3,
+ defaultContent: ''
+ },
+ {
+ title: lang.target_domain,
+ data: 'target_domain',
+ responsivePriority: 4,
+ defaultContent: ''
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
+ responsivePriority: 5,
+ defaultContent: ''
+ },
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-domain-aliases', '#aliasdomain_table');
+ });
}
function draw_sync_job_table() {
// just recalc width if instance already exists
@@ -1904,10 +2069,20 @@
return;
}
- $('#sync_job_table').DataTable({
+ var table = $('#sync_job_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,
+ order: [[2, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-syncjobs', '#sync_job_table');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/syncjobs/all/no_log",
@@ -1922,10 +2097,10 @@
}
item.server_w_port = escapeHtml(item.user1) + '@' + escapeHtml(item.host1) + ':' + escapeHtml(item.port1);
item.action = '<div class="btn-group">' +
- '<a href="/edit/syncjob/' + item.id + '" class="btn btn-sm btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-syncjob" data-api-url="delete/syncjob" data-item="' + item.id + '" class="btn btn-sm btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="/edit/syncjob/' + item.id + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-syncjob" data-api-url="delete/syncjob" data-item="' + item.id + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
- item.chkbox = '<input type="checkbox" data-id="syncjob" name="multi_select" value="' + item.id + '" />';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="syncjob" name="multi_select" value="' + item.id + '" />';
if (item.is_running == 1) {
item.is_running = '<span id="active-script" class="badge fs-6 bg-success">' + lang.running + '</span>';
} else {
@@ -1941,9 +2116,9 @@
item.success = '<i class="text-' + (item.success == 1 ? 'success' : 'danger') + ' bi bi-' + (item.success == 1 ? 'check-lg' : 'x-lg') + '"></i>';
}
if (lang['syncjob_'+item.exit_status]) {
- item.exit_status = lang['syncjob_'+item.exit_status];
+ item.exit_status = lang['syncjob_'+item.exit_status];
} else if (item.success != '-') {
- item.exit_status = lang.syncjob_check_log;
+ item.exit_status = lang.syncjob_check_log;
}
item.exit_status = item.success + ' ' + item.exit_status;
});
@@ -1952,89 +2127,93 @@
}
},
columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 2
- },
- {
- title: 'ID',
- data: 'id',
- responsivePriority: 3,
- defaultContent: ''
- },
- {
- title: lang.owner,
- data: 'user2',
- responsivePriority: 4,
- defaultContent: ''
- },
- {
- title: 'Server',
- data: 'server_w_port',
- defaultContent: ''
- },
- {
- title: lang.last_run,
- data: 'last_run',
- defaultContent: ''
- },
- {
- title: lang.syncjob_last_run_result,
- data: 'exit_status',
- defaultContent: ''
- },
- {
- title: 'Log',
- data: 'log',
- defaultContent: ''
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>';
- }
- },
- {
- title: lang.status,
- data: 'is_running',
- defaultContent: ''
- },
- {
- title: lang.excludes,
- data: 'exclude',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.mins_interval,
- data: 'mins_interval',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.action,
- data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-body-right',
- responsivePriority: 5,
- defaultContent: ''
- },
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 2
+ },
+ {
+ title: 'ID',
+ data: 'id',
+ responsivePriority: 3,
+ defaultContent: ''
+ },
+ {
+ title: lang.owner,
+ data: 'user2',
+ responsivePriority: 4,
+ defaultContent: ''
+ },
+ {
+ title: 'Server',
+ data: 'server_w_port',
+ defaultContent: ''
+ },
+ {
+ title: lang.last_run,
+ data: 'last_run',
+ defaultContent: ''
+ },
+ {
+ title: lang.syncjob_last_run_result,
+ data: 'exit_status',
+ defaultContent: ''
+ },
+ {
+ title: 'Log',
+ data: 'log',
+ defaultContent: ''
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"><span class="sorting-value">1</span></i>':0==data&&'<i class="bi bi-x-lg"><span class="sorting-value">0</span></i>';
+ }
+ },
+ {
+ title: lang.status,
+ data: 'is_running',
+ defaultContent: ''
+ },
+ {
+ title: lang.excludes,
+ data: 'exclude',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.mins_interval,
+ data: 'mins_interval',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
+ responsivePriority: 5,
+ defaultContent: ''
+ },
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-syncjobs', '#sync_job_table');
+ });
}
function draw_filter_table() {
// just recalc width if instance already exists
@@ -2044,10 +2223,20 @@
}
var table = $('#filter_table').DataTable({
+ responsive: true,
autoWidth: false,
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,
+ order: [[2, 'desc']],
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#tab-filters', '#filter_table');
+ },
ajax: {
type: "GET",
url: "/api/v1/get/filters/all",
@@ -2062,91 +2251,139 @@
item.script_data = '<pre class="text-break" style="margin:0px">' + escapeHtml(item.script_data) + '</pre>'
item.filter_type = '<div class="badge fs-6 bg-secondary">' + item.filter_type.charAt(0).toUpperCase() + item.filter_type.slice(1).toLowerCase() + '</div>'
item.action = '<div class="btn-group">' +
- '<a href="/edit/filter/' + item.id + '" class="btn btn-sm btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-filter" data-api-url="delete/filter" data-item="' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '<a href="/edit/filter/' + item.id + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-filter" data-api-url="delete/filter" data-item="' + encodeURIComponent(item.id) + '" class="btn btn-sm btn-xs-lg btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
'</div>';
- item.chkbox = '<input type="checkbox" data-id="filter_item" name="multi_select" value="' + item.id + '" />'
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="filter_item" name="multi_select" value="' + item.id + '" />'
});
return json;
}
},
columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 2
- },
- {
- title: 'ID',
- data: 'id',
- responsivePriority: 2,
- defaultContent: ''
- },
- {
- title: lang.active,
- data: 'active',
- responsivePriority: 3,
- defaultContent: ''
- },
- {
- title: 'Type',
- data: 'filter_type',
- responsivePriority: 4,
- defaultContent: ''
- },
- {
- title: lang.owner,
- data: 'username',
- defaultContent: ''
- },
- {
- title: lang.description,
- data: 'script_desc',
- defaultContent: ''
- },
- {
- title: 'Script',
- data: 'script_data',
- defaultContent: '',
- className: 'none'
- },
- {
- title: lang.action,
- data: 'action',
- className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-body-right',
- responsivePriority: 5,
- defaultContent: ''
- },
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 2
+ },
+ {
+ title: 'ID',
+ data: 'id',
+ responsivePriority: 2,
+ defaultContent: ''
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ responsivePriority: 3,
+ defaultContent: ''
+ },
+ {
+ title: 'Type',
+ data: 'filter_type',
+ responsivePriority: 4,
+ defaultContent: ''
+ },
+ {
+ title: lang.owner,
+ data: 'username',
+ defaultContent: ''
+ },
+ {
+ title: lang.description,
+ data: 'script_desc',
+ defaultContent: ''
+ },
+ {
+ title: 'Script',
+ data: 'script_data',
+ defaultContent: '',
+ className: 'none'
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-data-w100 dtr-col-md dt-text-right',
+ responsivePriority: 5,
+ defaultContent: ''
+ },
]
});
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#tab-filters', '#filter_table');
+ });
};
+ function hideTableExpandCollapseBtn(tab, table){
+ if ($(table).hasClass('collapsed'))
+ $(tab).find(".table_collapse_option").show();
+ else
+ $(tab).find(".table_collapse_option").hide();
+ }
+
+ function filterByDomain(json, column, table){
+ var tableId = $(table.table().container()).attr('id');
+ // Create the `select` element
+ var select = $('<select class="btn btn-sm btn-xs-lg btn-light text-start mx-2"><option value="">'+lang.all_domains+'</option></select>')
+ .insertBefore(
+ $('#'+tableId+' .dataTables_filter > label > input')
+ )
+ .on( 'change', function(){
+ table.column(column)
+ .search($(this).val())
+ .draw();
+ });
+
+ // get all domains
+ var domains = [];
+ json.forEach(obj => {
+ Object.entries(obj).forEach(([key, value]) => {
+ if(key === 'domain') {
+ domains.push(value)
+ }
+ });
+ });
+
+ // get unique domain list
+ domains = domains.filter(function(value, index, array) {
+ return array.indexOf(value) === index;
+ });
+
+ // add domains to select
+ domains.forEach(function(domain) {
+ select.append($('<option>' + domain + '</option>'));
+ });
+ }
+
// detect element visibility changes
function onVisible(element, callback) {
$(document).ready(function() {
- element_object = document.querySelector(element);
+ let element_object = document.querySelector(element);
if (element_object === null) return;
- new IntersectionObserver((entries, observer) => {
+ let observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if(entry.intersectionRatio > 0) {
callback(element_object);
+ observer.unobserve(element_object);
}
});
- }).observe(element_object);
+ })
+
+ observer.observe(element_object);
});
}
diff --git a/mailcow/src/mailcow-dockerized/data/web/js/site/qhandler.js b/mailcow/src/mailcow-dockerized/data/web/js/site/qhandler.js
index 4fcc963..8a8471f 100644
--- a/mailcow/src/mailcow-dockerized/data/web/js/site/qhandler.js
+++ b/mailcow/src/mailcow-dockerized/data/web/js/site/qhandler.js
@@ -1,71 +1,71 @@
-jQuery(function($){
- var qitem = $('legend').data('hash');
- var qError = $("#qid_error");
- $.ajax({
- url: '/inc/ajax/qitem_details.php',
- data: { hash: qitem },
- dataType: 'json',
- success: function(data){
- $('[data-id="qitems_single"]').each(function(index) {
- $(this).attr("data-item", qitem);
- });
- $('#qid_detail_subj').text(data.subject);
- $('#qid_detail_hfrom').text(data.header_from);
- $('#qid_detail_efrom').text(data.env_from);
- $('#qid_detail_score').html('');
- $('#qid_detail_symbols').html('');
- $('#qid_detail_recipients').html('');
- $('#qid_detail_fuzzy').html('');
- if (typeof data.fuzzy_hashes === 'object' && data.fuzzy_hashes !== null && data.fuzzy_hashes.length !== 0) {
- $.each(data.fuzzy_hashes, function (index, value) {
- $('#qid_detail_fuzzy').append('<p style="font-family:monospace">' + value + '</p>');
- });
- } else {
- $('#qid_detail_fuzzy').append('-');
- }
- if (typeof data.symbols !== 'undefined') {
- data.symbols.sort(function (a, b) {
- if (a.score === 0) return 1
- if (b.score === 0) return -1
- if (b.score < 0 && a.score < 0) {
- return a.score - b.score
- }
- if (b.score > 0 && a.score > 0) {
- return b.score - a.score
- }
- return b.score - a.score
- })
- $.each(data.symbols, function (index, value) {
- var highlightClass = ''
- if (value.score > 0) highlightClass = 'negative'
- else if (value.score < 0) highlightClass = 'positive'
- else highlightClass = 'neutral'
- $('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
- });
- $('[data-bs-toggle="tooltip"]').tooltip()
- }
- if (typeof data.score !== 'undefined' && typeof data.action !== 'undefined') {
- if (data.action === "add header") {
- $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
- } else if (data.action === "reject") {
- $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
- } else if (data.action === "rewrite subject") {
- $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
- }
- }
- if (typeof data.recipients !== 'undefined') {
- $.each(data.recipients, function(index, value) {
- var elem = $('<span class="mail-address-item"></span>');
- elem.text(value.address + ' (' + value.type.toUpperCase() + ')');
- $('#qid_detail_recipients').append(elem);
- });
- }
- },
- error: function(data){
- if (typeof data.error !== 'undefined') {
- qError.text("Error loading quarantine item");
- qError.show();
- }
- }
- });
-});
+jQuery(function($){
+ var qitem = $('legend').data('hash');
+ var qError = $("#qid_error");
+ $.ajax({
+ url: '/inc/ajax/qitem_details.php',
+ data: { hash: qitem },
+ dataType: 'json',
+ success: function(data){
+ $('[data-id="qitems_single"]').each(function(index) {
+ $(this).attr("data-item", qitem);
+ });
+ $('#qid_detail_subj').text(data.subject);
+ $('#qid_detail_hfrom').text(data.header_from);
+ $('#qid_detail_efrom').text(data.env_from);
+ $('#qid_detail_score').html('');
+ $('#qid_detail_symbols').html('');
+ $('#qid_detail_recipients').html('');
+ $('#qid_detail_fuzzy').html('');
+ if (typeof data.fuzzy_hashes === 'object' && data.fuzzy_hashes !== null && data.fuzzy_hashes.length !== 0) {
+ $.each(data.fuzzy_hashes, function (index, value) {
+ $('#qid_detail_fuzzy').append('<p style="font-family:monospace">' + value + '</p>');
+ });
+ } else {
+ $('#qid_detail_fuzzy').append('-');
+ }
+ if (typeof data.symbols !== 'undefined') {
+ data.symbols.sort(function (a, b) {
+ if (a.score === 0) return 1;
+ if (b.score === 0) return -1;
+ if (b.score < 0 && a.score < 0) {
+ return a.score - b.score;
+ }
+ if (b.score > 0 && a.score > 0) {
+ return b.score - a.score;
+ }
+ return b.score - a.score;
+ })
+ $.each(data.symbols, function (index, value) {
+ var highlightClass = '';
+ if (value.score > 0) highlightClass = 'negative';
+ else if (value.score < 0) highlightClass = 'positive';
+ else highlightClass = 'neutral';
+ $('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
+ });
+ $('[data-bs-toggle="tooltip"]').tooltip();
+ }
+ if (typeof data.score !== 'undefined' && typeof data.action !== 'undefined') {
+ if (data.action === "add header") {
+ $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
+ } else if (data.action === "reject") {
+ $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
+ } else if (data.action === "rewrite subject") {
+ $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
+ }
+ }
+ if (typeof data.recipients !== 'undefined') {
+ $.each(data.recipients, function(index, value) {
+ var elem = $('<span class="mail-address-item"></span>');
+ elem.text(value.address + ' (' + value.type.toUpperCase() + ')');
+ $('#qid_detail_recipients').append(elem);
+ });
+ }
+ },
+ error: function(data){
+ if (typeof data.error !== 'undefined') {
+ qError.text("Error loading quarantine item");
+ qError.show();
+ }
+ }
+ });
+});
diff --git a/mailcow/src/mailcow-dockerized/data/web/js/site/quarantine.js b/mailcow/src/mailcow-dockerized/data/web/js/site/quarantine.js
index 34531b0..8d7f222 100644
--- a/mailcow/src/mailcow-dockerized/data/web/js/site/quarantine.js
+++ b/mailcow/src/mailcow-dockerized/data/web/js/site/quarantine.js
@@ -1,260 +1,297 @@
-// 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<r.length;)a=(t=r.charCodeAt(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<r.length;)t=this._keyStr.indexOf(r.charAt(d++))<<2|(a=this._keyStr.indexOf(r.charAt(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;e<r.length;e++){var o=r.charCodeAt(e);o<128?t+=String.fromCharCode(o):o>127&&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;e<r.length;)(o=r.charCodeAt(e))<128?(t+=String.fromCharCode(o),e++):o>191&&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($){
- acl_data = JSON.parse(acl);
- // http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery
- var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};
- function escapeHtml(n){return String(n).replace(/[&<>"'`=\/]/g,function(n){return entityMap[n]})}
- 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<B.length-1);return i.toFixed(1)+" "+B[e]}
- $(".refresh_table").on('click', function(e) {
- e.preventDefault();
- var table_name = $(this).data('table');
- $('#' + table_name).DataTable().ajax.reload();
- });
- function draw_quarantine_table() {
- $('#quarantinetable').DataTable({
- processing: true,
- serverSide: false,
- language: lang_datatables,
- ajax: {
- type: "GET",
- url: "/api/v1/get/quarantine/all",
- dataSrc: function(data){
- $.each(data, function (i, item) {
- if (item.subject === null) {
- item.subject = '';
- } else {
- item.subject = escapeHtml(item.subject);
- }
- if (item.score === null) {
- item.score = '-';
- }
- if (item.virus_flag > 0) {
- item.virus = '<span class="badge fs-6 bg-danger">' + lang.high_danger + '</span>';
- } else {
- item.virus = '<span class="badge fs-6 bg-secondary">' + lang.neutral_danger + '</span>';
- }
- if (item.action === "reject") {
- item.rspamdaction = '<span class="badge fs-6 bg-danger">' + lang.rejected + '</span>';
- } else if (item.action === "add header") {
- item.rspamdaction = '<span class="badge fs-6 bg-warning">' + lang.junk_folder + '</span>';
- } else if (item.action === "rewrite subject") {
- item.rspamdaction = '<span class="badge fs-6 bg-warning">' + lang.rewrite_subject + '</span>';
- }
- if(item.notified > 0) {
- item.notified = '✔';
- } else {
- item.notified = '✖';
- }
- if (acl_data.login_as === 1) {
- item.action = '<div class="btn-group">' +
- '<a href="#" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-info show_qid_info"><i class="bi bi-box-arrow-up-right"></i> ' + lang.show_item + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="del-single-qitem" data-api-url="delete/qitem" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- }
- else {
- item.action = '<div class="btn-group">' +
- '<a href="#" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-info show_qid_info"><i class="bi bi-file-earmark-text"></i> ' + lang.show_item + '</a>' +
- '</div>';
- }
- item.chkbox = '<input type="checkbox" data-id="qitems" name="multi_select" value="' + item.id + '" />';
- });
-
- 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: 'id',
- defaultContent: ''
- },
- {
- title: lang.qid,
- data: 'qid',
- defaultContent: ''
- },
- {
- title: lang.sender,
- data: 'sender',
- defaultContent: ''
- },
- {
- title: lang.subj,
- data: 'subject',
- defaultContent: ''
- },
- {
- title: lang.rspamd_result,
- data: 'rspamdaction',
- defaultContent: ''
- },
- {
- title: lang.rcpt,
- data: 'rcpt',
- defaultContent: ''
- },
- {
- title: lang.danger,
- data: 'virus',
- defaultContent: ''
- },
- {
- title: lang.spam_score,
- data: 'score',
- defaultContent: ''
- },
- {
- title: lang.notified,
- data: 'notified',
- defaultContent: ''
- },
- {
- title: lang.received,
- data: 'created',
- defaultContent: '',
- 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"});
- }
- },
- {
- title: lang.action,
- data: 'action',
- className: 'text-md-end dt-sm-head-hidden dt-body-right',
- defaultContent: ''
- },
- ]
- });
- }
-
- $('body').on('click', '.show_qid_info', function (e) {
- e.preventDefault();
- var qitem = $(this).attr('data-item');
- var qError = $("#qid_error");
-
- $('#qidDetailModal').modal('show');
- qError.hide();
-
- $.ajax({
- url: '/inc/ajax/qitem_details.php',
- data: { id: qitem },
- dataType: 'json',
- success: function(data){
-
- $('[data-id="qitems_single"]').each(function(index) {
- $(this).attr("data-item", qitem);
- });
-
- $("#quick_download_link").attr("onclick", "window.open('/inc/ajax/qitem_details.php?id=" + qitem + "&eml', '_blank')");
- $("#quick_release_link").attr("onclick", "window.open('/inc/ajax/qitem_details.php?id=" + qitem + "&quick_release', '_blank')");
- $("#quick_delete_link").attr("onclick", "window.open('/inc/ajax/qitem_details.php?id=" + qitem + "&quick_delete', '_blank')");
-
- $('#qid_detail_subj').text(data.subject);
- $('#qid_detail_hfrom').text(data.header_from);
- $('#qid_detail_efrom').text(data.env_from);
- $('#qid_detail_score').html('');
- $('#qid_detail_recipients').html('');
- $('#qid_detail_symbols').html('');
- $('#qid_detail_fuzzy').html('');
- if (typeof data.symbols !== 'undefined') {
- data.symbols.sort(function (a, b) {
- if (a.score === 0) return 1
- if (b.score === 0) return -1
- if (b.score < 0 && a.score < 0) {
- return a.score - b.score
- }
- if (b.score > 0 && a.score > 0) {
- return b.score - a.score
- }
- return b.score - a.score
- })
- $.each(data.symbols, function (index, value) {
- var highlightClass = ''
- if (value.score > 0) highlightClass = 'negative'
- else if (value.score < 0) highlightClass = 'positive'
- else highlightClass = 'neutral'
- $('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
- });
- $('[data-bs-toggle="tooltip"]').tooltip()
- }
- if (typeof data.fuzzy_hashes === 'object' && data.fuzzy_hashes !== null && data.fuzzy_hashes.length !== 0) {
- $.each(data.fuzzy_hashes, function (index, value) {
- $('#qid_detail_fuzzy').append('<p style="font-family:monospace">' + value + '</p>');
- });
- } else {
- $('#qid_detail_fuzzy').append('-');
- }
- if (typeof data.score !== 'undefined' && typeof data.action !== 'undefined') {
- if (data.action == "add header") {
- $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
- } else if (data.action == "reject") {
- $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
- } else if (data.action == "rewrite subject") {
- $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
- }
- }
- if (typeof data.recipients !== 'undefined') {
- $.each(data.recipients, function(index, value) {
- var elem = $('<span class="mail-address-item"></span>');
- elem.text(value.address + ' (' + value.type.toUpperCase() + ')');
- $('#qid_detail_recipients').append(elem);
- });
- }
- $('#qid_detail_text').text(data.text_plain);
- $('#qid_detail_text_from_html').text(data.text_html);
- var qAtts = $("#qid_detail_atts");
- if (typeof data.attachments !== 'undefined') {
- qAtts.text('');
- $.each(data.attachments, function(index, value) {
- qAtts.append(
- '<p><a href="/inc/ajax/qitem_details.php?id=' + qitem + '&att=' + index + '" target="_blank">' + value[0] + '</a> (' + value[1] + ')' +
- ' - <small><a href="' + value[3] + '" target="_blank">' + lang.check_hash + '</a></small></p>'
- );
- });
- }
- else {
- qAtts.text('-');
- }
- },
- error: function(data){
- if (typeof data.error !== 'undefined') {
- $('#qid_detail_subj').text('-');
- $('#qid_detail_hfrom').text('-');
- $('#qid_detail_efrom').text('-');
- $('#qid_detail_score').html('-');
- $('#qid_detail_recipients').html('-');
- $('#qid_detail_symbols').html('-');
- $('#qid_detail_fuzzy').html('-');
- $('#qid_detail_text').text('-');
- $('#qid_detail_text_from_html').text('-');
- qError.text("Error loading quarantine item");
- qError.show();
- }
- }
- });
- });
-
- $('body').on('click', 'span.footable-toggle', function () {
- event.stopPropagation();
- })
-
- // Initial table drawings
- draw_quarantine_table();
-});
+// 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<r.length;)a=(t=r.charCodeAt(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<r.length;)t=this._keyStr.indexOf(r.charAt(d++))<<2|(a=this._keyStr.indexOf(r.charAt(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;e<r.length;e++){var o=r.charCodeAt(e);o<128?t+=String.fromCharCode(o):o>127&&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;e<r.length;)(o=r.charCodeAt(e))<128?(t+=String.fromCharCode(o),e++):o>191&&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($){
+ acl_data = JSON.parse(acl);
+ // http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery
+ var entityMap={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};
+ function escapeHtml(n){return String(n).replace(/[&<>"'`=\/]/g,function(n){return entityMap[n]})}
+ 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<B.length-1);return i.toFixed(1)+" "+B[e]}
+ $(".refresh_table").on('click', function(e) {
+ e.preventDefault();
+ var table_name = $(this).data('table');
+ $('#' + table_name).DataTable().ajax.reload();
+ });
+ function draw_quarantine_table() {
+ var table = $('#quarantinetable').DataTable({
+ responsive: true,
+ processing: true,
+ serverSide: false,
+ stateSave: true,
+ pageLength: pagination_size,
+ order: [[2, 'desc']],
+ lengthMenu: [
+ [10, 25, 50, 100, -1],
+ [10, 25, 50, 100, 'all']
+ ],
+ pagingType: 'first_last_numbers',
+ aColumns: [
+ { sWidth: '8.25%' },
+ { sClass: 'classDataTable' }
+ ],
+ 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,
+ initComplete: function(){
+ hideTableExpandCollapseBtn('#quarantinetable');
+ },
+ ajax: {
+ type: "GET",
+ url: "/api/v1/get/quarantine/all",
+ dataSrc: function(data){
+ $.each(data, function (i, item) {
+ if (item.subject === null) {
+ item.subject = '';
+ } else {
+ item.subject = escapeHtml(item.subject);
+ }
+ if (item.score === null) {
+ item.score = '-';
+ }
+ if (item.virus_flag > 0) {
+ item.virus = '<span class="badge fs-6 bg-danger">' + lang.high_danger + '</span>';
+ } else {
+ item.virus = '<span class="badge fs-6 bg-secondary">' + lang.neutral_danger + '</span>';
+ }
+ if (item.action === "reject") {
+ item.rspamdaction = '<span class="badge fs-6 bg-danger">' + lang.rejected + '</span>';
+ } else if (item.action === "add header") {
+ item.rspamdaction = '<span class="badge fs-6 bg-warning">' + lang.junk_folder + '</span>';
+ } else if (item.action === "rewrite subject") {
+ item.rspamdaction = '<span class="badge fs-6 bg-warning">' + lang.rewrite_subject + '</span>';
+ }
+ if(item.notified > 0) {
+ item.notified = '✔';
+ } else {
+ item.notified = '✖';
+ }
+ if (acl_data.login_as === 1) {
+ item.action = '<div class="btn-group">' +
+ '<a href="#" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-info show_qid_info"><i class="bi bi-box-arrow-up-right"></i> ' + lang.show_item + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="del-single-qitem" data-api-url="delete/qitem" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ }
+ else {
+ item.action = '<div class="btn-group">' +
+ '<a href="#" data-item="' + encodeURI(item.id) + '" class="btn btn-xs btn-info show_qid_info"><i class="bi bi-file-earmark-text"></i> ' + lang.show_item + '</a>' +
+ '</div>';
+ }
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="qitems" name="multi_select" value="' + item.id + '" />';
+ });
+
+ 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: 'id',
+ defaultContent: ''
+ },
+ {
+ title: lang.qid,
+ data: 'qid',
+ defaultContent: ''
+ },
+ {
+ title: lang.sender,
+ data: 'sender',
+ className: 'senders-mw220',
+ defaultContent: ''
+ },
+ {
+ title: lang.subj,
+ data: 'subject',
+ defaultContent: ''
+ },
+ {
+ title: lang.rspamd_result,
+ data: 'rspamdaction',
+ defaultContent: ''
+ },
+ {
+ title: lang.rcpt,
+ data: 'rcpt',
+ defaultContent: ''
+ },
+ {
+ title: lang.danger,
+ data: 'virus',
+ defaultContent: ''
+ },
+ {
+ title: lang.spam_score,
+ data: 'score',
+ defaultContent: ''
+ },
+ {
+ title: lang.notified,
+ data: 'notified',
+ defaultContent: ''
+ },
+ {
+ title: lang.received,
+ data: 'created',
+ defaultContent: '',
+ createdCell: function(td, cellData) {
+ $(td).attr({
+ "data-order": cellData,
+ "data-sort": cellData
+ });
+
+ var date = new Date(cellData ? cellData * 1000 : 0);
+ var dateString = date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
+ $(td).html(dateString);
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-text-right dt-sm-head-hidden',
+ defaultContent: ''
+ },
+ ]
+ });
+
+ table.on('responsive-resize', function (e, datatable, columns){
+ hideTableExpandCollapseBtn('#quarantinetable');
+ });
+ }
+
+ $('body').on('click', '.show_qid_info', function (e) {
+ e.preventDefault();
+ var qitem = $(this).attr('data-item');
+ var qError = $("#qid_error");
+
+ $('#qidDetailModal').modal('show');
+ qError.hide();
+
+ $.ajax({
+ url: '/inc/ajax/qitem_details.php',
+ data: { id: qitem },
+ dataType: 'json',
+ success: function(data){
+
+ $('[data-id="qitems_single"]').each(function(index) {
+ $(this).attr("data-item", qitem);
+ });
+
+ $("#quick_download_link").attr("onclick", "window.open('/inc/ajax/qitem_details.php?id=" + qitem + "&eml', '_blank')");
+ $("#quick_release_link").attr("onclick", "window.open('/inc/ajax/qitem_details.php?id=" + qitem + "&quick_release', '_blank')");
+ $("#quick_delete_link").attr("onclick", "window.open('/inc/ajax/qitem_details.php?id=" + qitem + "&quick_delete', '_blank')");
+
+ $('#qid_detail_subj').text(data.subject);
+ $('#qid_detail_hfrom').text(data.header_from);
+ $('#qid_detail_efrom').text(data.env_from);
+ $('#qid_detail_score').html('');
+ $('#qid_detail_recipients').html('');
+ $('#qid_detail_symbols').html('');
+ $('#qid_detail_fuzzy').html('');
+ if (typeof data.symbols !== 'undefined') {
+ data.symbols.sort(function (a, b) {
+ if (a.score === 0) return 1;
+ if (b.score === 0) return -1;
+ if (b.score < 0 && a.score < 0) {
+ return a.score - b.score;
+ }
+ if (b.score > 0 && a.score > 0) {
+ return b.score - a.score;
+ }
+ return b.score - a.score;
+ })
+ $.each(data.symbols, function (index, value) {
+ var highlightClass = '';
+ if (value.score > 0) highlightClass = 'negative';
+ else if (value.score < 0) highlightClass = 'positive';
+ else highlightClass = 'neutral';
+ $('#qid_detail_symbols').append('<span data-bs-toggle="tooltip" class="rspamd-symbol ' + highlightClass + '" title="' + (value.options ? value.options.join(', ') : '') + '">' + value.name + ' (<span class="score">' + value.score + '</span>)</span>');
+ });
+ $('[data-bs-toggle="tooltip"]').tooltip();
+ }
+ if (typeof data.fuzzy_hashes === 'object' && data.fuzzy_hashes !== null && data.fuzzy_hashes.length !== 0) {
+ $.each(data.fuzzy_hashes, function (index, value) {
+ $('#qid_detail_fuzzy').append('<p style="font-family:monospace">' + value + '</p>');
+ });
+ } else {
+ $('#qid_detail_fuzzy').append('-');
+ }
+ if (typeof data.score !== 'undefined' && typeof data.action !== 'undefined') {
+ if (data.action == "add header") {
+ $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-warning"><b>' + data.score + '</b> - ' + lang.junk_folder + '</span>');
+ } else if (data.action == "reject") {
+ $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-danger"><b>' + data.score + '</b> - ' + lang.rejected + '</span>');
+ } else if (data.action == "rewrite subject") {
+ $('#qid_detail_score').append('<span class="label-rspamd-action badge fs-6 bg-warning"><b>' + data.score + '</b> - ' + lang.rewrite_subject + '</span>');
+ }
+ }
+ if (typeof data.recipients !== 'undefined') {
+ $.each(data.recipients, function(index, value) {
+ var elem = $('<span class="mail-address-item"></span>');
+ elem.text(value.address + ' (' + value.type.toUpperCase() + ')');
+ $('#qid_detail_recipients').append(elem);
+ });
+ }
+ $('#qid_detail_text').text(data.text_plain);
+ $('#qid_detail_text_from_html').text(data.text_html);
+ var qAtts = $("#qid_detail_atts");
+ if (typeof data.attachments !== 'undefined') {
+ qAtts.text('');
+ $.each(data.attachments, function(index, value) {
+ qAtts.append(
+ '<p><a href="/inc/ajax/qitem_details.php?id=' + qitem + '&att=' + index + '" target="_blank">' + value[0] + '</a> (' + value[1] + ')' +
+ ' - <small><a href="' + value[3] + '" target="_blank">' + lang.check_hash + '</a></small></p>'
+ );
+ });
+ }
+ else {
+ qAtts.text('-');
+ }
+ },
+ error: function(data){
+ if (typeof data.error !== 'undefined') {
+ $('#qid_detail_subj').text('-');
+ $('#qid_detail_hfrom').text('-');
+ $('#qid_detail_efrom').text('-');
+ $('#qid_detail_score').html('-');
+ $('#qid_detail_recipients').html('-');
+ $('#qid_detail_symbols').html('-');
+ $('#qid_detail_fuzzy').html('-');
+ $('#qid_detail_text').text('-');
+ $('#qid_detail_text_from_html').text('-');
+ qError.text("Error loading quarantine item");
+ qError.show();
+ }
+ }
+ });
+ });
+
+ $('body').on('click', 'span.footable-toggle', function () {
+ event.stopPropagation();
+ })
+
+ // Initial table drawings
+ draw_quarantine_table();
+
+ function hideTableExpandCollapseBtn(table){
+ if ($(table).hasClass('collapsed'))
+ $(".table_collapse_option").show();
+ else
+ $(".table_collapse_option").hide();
+ }
+});
diff --git a/mailcow/src/mailcow-dockerized/data/web/js/site/queue.js b/mailcow/src/mailcow-dockerized/data/web/js/site/queue.js
index 057ad84..26c1509 100644
--- a/mailcow/src/mailcow-dockerized/data/web/js/site/queue.js
+++ b/mailcow/src/mailcow-dockerized/data/web/js/site/queue.js
@@ -1,123 +1,128 @@
jQuery(function($){
- $(".refresh_table").on('click', function(e) {
- e.preventDefault();
- var table_name = $(this).data('table');
- $('#' + table_name).DataTable().ajax.reload();
- });
+ $(".refresh_table").on('click', function(e) {
+ e.preventDefault();
+ var table_name = $(this).data('table');
+ $('#' + table_name).DataTable().ajax.reload();
+ });
- 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<B.length-1);return i.toFixed(1)+" "+B[e]}
+ 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<B.length-1);return i.toFixed(1)+" "+B[e]}
- // Queue item
- $('#showQueuedMsg').on('show.bs.modal', function (e) {
- $('#queue_msg_content').text(lang.loading);
- button = $(e.relatedTarget)
- if (button != null) {
- $('#queue_id').text(button.data('queue-id'));
- }
- $.ajax({
- type: 'GET',
- url: '/api/v1/get/postcat/' + button.data('queue-id'),
- dataType: 'text',
- complete: function (data) {
- console.log(data);
- $('#queue_msg_content').text(data.responseText);
- }
- });
- })
-
- function draw_queue() {
- // just recalc width if instance already exists
- if ($.fn.DataTable.isDataTable('#queuetable') ) {
- $('#queuetable').DataTable().columns.adjust().responsive.recalc();
- return;
+ // Queue item
+ $('#showQueuedMsg').on('show.bs.modal', function (e) {
+ $('#queue_msg_content').text(lang.loading);
+ button = $(e.relatedTarget)
+ if (button != null) {
+ $('#queue_id').text(button.data('queue-id'));
}
+ $.ajax({
+ type: 'GET',
+ url: '/api/v1/get/postcat/' + button.data('queue-id'),
+ dataType: 'text',
+ complete: function (data) {
+ $('#queue_msg_content').text(data.responseText);
+ }
+ });
+ })
- $('#queuetable').DataTable({
- processing: true,
- serverSide: false,
- language: lang_datatables,
- ajax: {
- type: "GET",
- url: "/api/v1/get/mailq/all",
- dataSrc: function(data){
- $.each(data, function (i, item) {
- item.chkbox = '<input type="checkbox" data-id="mailqitems" name="multi_select" value="' + item.queue_id + '" />';
- rcpts = $.map(item.recipients, function(i) {
- return escapeHtml(i);
- });
- item.recipients = rcpts.join('<hr style="margin:1px!important">');
- item.action = '<div class="btn-group">' +
- '<a href="#" data-bs-toggle="modal" data-bs-target="#showQueuedMsg" data-queue-id="' + encodeURI(item.queue_id) + '" class="btn btn-xs btn-secondary">' + lang.queue_show_message + '</a>' +
+ function draw_queue() {
+ // just recalc width if instance already exists
+ if ($.fn.DataTable.isDataTable('#queuetable') ) {
+ $('#queuetable').DataTable().columns.adjust().responsive.recalc();
+ return;
+ }
+
+ $('#queuetable').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/mailq/all",
+ dataSrc: function(data){
+ $.each(data, function (i, item) {
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="mailqitems" name="multi_select" value="' + item.queue_id + '" />';
+ rcpts = $.map(item.recipients, function(i) {
+ return escapeHtml(i);
+ });
+ item.recipients = rcpts.join('<hr style="margin:1px!important">');
+ item.action = '<div class="btn-group">' +
+ '<a href="#" data-bs-toggle="modal" data-bs-target="#showQueuedMsg" data-queue-id="' + encodeURI(item.queue_id) + '" class="btn btn-xs btn-secondary">' + lang.show_message + '</a>' +
'</div>';
});
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: 'QID',
- data: 'queue_id',
- defaultContent: ''
- },
- {
- title: 'Queue',
- data: 'queue_name',
- defaultContent: ''
- },
- {
- title: lang_admin.arrival_time,
- data: 'arrival_time',
- defaultContent: '',
- 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"});
- }
- },
- {
- title: lang_admin.message_size,
- data: 'message_size',
- defaultContent: '',
- render: function (data, type){
- return humanFileSize(data);
- }
- },
- {
- title: lang_admin.sender,
- data: 'sender',
- defaultContent: ''
- },
- {
- title: lang_admin.recipients,
- data: 'recipients',
- defaultContent: ''
- },
- {
- title: lang_admin.action,
- data: 'action',
- className: 'text-md-end dt-sm-head-hidden dt-body-right',
- defaultContent: ''
- },
+ {
+ // 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: 'QID',
+ data: 'queue_id',
+ defaultContent: ''
+ },
+ {
+ title: 'Queue',
+ data: 'queue_name',
+ defaultContent: ''
+ },
+ {
+ title: lang_admin.arrival_time,
+ data: 'arrival_time',
+ defaultContent: '',
+ 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"});
+ }
+ },
+ {
+ title: lang_admin.message_size,
+ data: 'message_size',
+ defaultContent: '',
+ render: function (data, type){
+ return humanFileSize(data);
+ }
+ },
+ {
+ title: lang_admin.sender,
+ data: 'sender',
+ defaultContent: ''
+ },
+ {
+ title: lang_admin.recipients,
+ data: 'recipients',
+ defaultContent: ''
+ },
+ {
+ title: lang_admin.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-text-right',
+ defaultContent: ''
+ },
]
});
}
draw_queue();
-})
\ No newline at end of file
+})
diff --git a/mailcow/src/mailcow-dockerized/data/web/js/site/user.js b/mailcow/src/mailcow-dockerized/data/web/js/site/user.js
index 36bcfa6..088321c 100644
--- a/mailcow/src/mailcow-dockerized/data/web/js/site/user.js
+++ b/mailcow/src/mailcow-dockerized/data/web/js/site/user.js
@@ -1,637 +1,680 @@
-// 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<r.length;)a=(t=r.charCodeAt(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<r.length;)t=this._keyStr.indexOf(r.charAt(d++))<<2|(a=this._keyStr.indexOf(r.charAt(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;e<r.length;e++){var o=r.charCodeAt(e);o<128?t+=String.fromCharCode(o):o>127&&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;e<r.length;)(o=r.charCodeAt(e))<128?(t+=String.fromCharCode(o),e++):o>191&&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}};
-$(document).ready(function() {
- // Spam score slider
- var spam_slider = $('#spam_score')[0];
- if (typeof spam_slider !== 'undefined') {
- noUiSlider.create(spam_slider, {
- start: user_spam_score,
- connect: [true, true, true],
- range: {
- 'min': [0], //stepsize is 50.000
- '50%': [10],
- '70%': [20, 5],
- '80%': [50, 10],
- '90%': [100, 100],
- '95%': [1000, 1000],
- 'max': [5000]
- },
- });
- var connect = spam_slider.querySelectorAll('.noUi-connect');
- var classes = ['c-1-color', 'c-2-color', 'c-3-color'];
- for (var i = 0; i < connect.length; i++) {
- connect[i].classList.add(classes[i]);
- }
- spam_slider.noUiSlider.on('update', function (values, handle) {
- $('.spam-ham-score').text('< ' + Math.round(values[0] * 10) / 10);
- $('.spam-spam-score').text(Math.round(values[0] * 10) / 10 + ' - ' + Math.round(values[1] * 10) / 10);
- $('.spam-reject-score').text('> ' + Math.round(values[1] * 10) / 10);
- $('#spam_score_value').val((Math.round(values[0] * 10) / 10) + ',' + (Math.round(values[1] * 10) / 10));
- });
- }
- // syncjobLogModal
- $('#syncjobLogModal').on('show.bs.modal', function(e) {
- var syncjob_id = $(e.relatedTarget).data('syncjob-id');
- $.ajax({
- url: '/inc/ajax/syncjob_logs.php',
- data: { id: syncjob_id },
- dataType: 'text',
- success: function(data){
- $(e.currentTarget).find('#logText').text(data);
- },
- error: function(xhr, status, error) {
- $(e.currentTarget).find('#logText').text(xhr.responseText);
- }
- });
- });
- $(".arrow-toggle").on('click', function(e) { e.preventDefault(); $(this).find('.arrow').toggleClass("animation"); });
- $("#pushover_delete").click(function() { return confirm(lang.delete_ays); });
-
-});
-jQuery(function($){
- // http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery
- var entityMap = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"',
- "'": ''',
- '/': '/',
- '`': '`',
- '=': '='
- };
- function escapeHtml(string) {
- return String(string).replace(/[&<>"'`=\/]/g, function (s) {
- return entityMap[s];
- });
- }
- // 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 unix_time_format(tm) {
- var date = new Date(tm ? tm * 1000 : 0);
- return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
- }
- acl_data = JSON.parse(acl);
-
- $('.clear-last-logins').on('click', function () {if (confirm(lang.delete_ays)) {last_logins('reset');}})
- $(".login-history").on('click', function(e) {e.preventDefault(); last_logins('get', $(this).data('days'));$(this).addClass('active').siblings().removeClass('active');});
-
- function last_logins(action, days = 7) {
- if (action == 'get') {
- $('.last-login').html('<i class="bi bi-hourglass"></i>' + lang.waiting);
- $.ajax({
- dataType: 'json',
- url: '/api/v1/get/last-login/' + encodeURIComponent(mailcow_cc_username) + '/' + days,
- jsonp: false,
- error: function () {
- console.log('error reading last logins');
- },
- success: function (data) {
- $('.last-login').html();
- if (data.ui.time) {
- $('.last-login').html('<i class="bi bi-person-fill"></i> ' + lang.last_ui_login + ': ' + unix_time_format(data.ui.time));
- } else {
- $('.last-login').text(lang.no_last_login);
- }
- if (data.sasl) {
- $('.last-login').append('<ul class="list-group">');
- $.each(data.sasl, function (i, item) {
- var datetime = new Date(item.datetime.replace(/-/g, "/"));
- var local_datetime = datetime.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
- var service = '<div class="badge fs-6 bg-secondary">' + item.service.toUpperCase() + '</div>';
- var app_password = item.app_password ? ' <a href="/edit/app-passwd/' + item.app_password + '"><i class="bi bi-app-indicator"></i> ' + escapeHtml(item.app_password_name || "App") + '</a>' : '';
- var real_rip = item.real_rip.startsWith("Web") ? item.real_rip : '<a href="https://bgp.he.net/ip/' + item.real_rip + '" target="_blank">' + item.real_rip + "</a>";
- var ip_location = item.location ? ' <span class="flag-icon flag-icon-' + item.location.toLowerCase() + '"></span>' : '';
- var ip_data = real_rip + ip_location + app_password;
- $(".last-login").append('<li class="list-group-item">' + local_datetime + " " + service + " " + lang.from + " " + ip_data + "</li>");
- })
- $('.last-login').append('</ul>');
- }
- }
- })
- } else if (action == 'reset') {
- $.ajax({
- dataType: 'json',
- url: '/api/v1/get/reset-last-login/' + encodeURIComponent(mailcow_cc_username),
- jsonp: false,
- error: function () {
- console.log('cannot reset last logins');
- },
- success: function (data) {
- last_logins('get');
- }
- })
- }
- }
-
- function draw_tla_table() {
- // just recalc width if instance already exists
- if ($.fn.DataTable.isDataTable('#tla_table') ) {
- $('#tla_table').DataTable().columns.adjust().responsive.recalc();
- return;
- }
-
- $('#tla_table').DataTable({
- processing: true,
- serverSide: false,
- language: lang_datatables,
- ajax: {
- type: "GET",
- url: "/api/v1/get/time_limited_aliases",
- dataSrc: function(data){
- console.log(data);
- $.each(data, function (i, item) {
- if (acl_data.spam_alias === 1) {
- item.action = '<div class="btn-group">' +
- '<a href="#" data-action="delete_selected" data-id="single-tla" data-api-url="delete/time_limited_alias" data-item="' + encodeURIComponent(item.address) + '" class="btn btn-xs btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- item.chkbox = '<input type="checkbox" data-id="tla" name="multi_select" value="' + encodeURIComponent(item.address) + '" />';
- item.address = escapeHtml(item.address);
- }
- else {
- item.chkbox = '<input type="checkbox" disabled />';
- item.action = '<span>-</span>';
- }
- });
-
- 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: lang.alias,
- data: 'address',
- defaultContent: ''
- },
- {
- title: lang.alias_valid_until,
- data: 'validity',
- defaultContent: '',
- 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"});
- }
- },
- {
- title: lang.created_on,
- data: 'created',
- defaultContent: '',
- render: function (data, type) {
- var date = new Date(data.replace(/-/g, "/"));
- return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
- }
- },
- {
- title: lang.action,
- data: 'action',
- className: 'text-md-end dt-sm-head-hidden dt-body-right',
- defaultContent: ''
- }
- ]
- });
- }
- function draw_sync_job_table() {
- // just recalc width if instance already exists
- if ($.fn.DataTable.isDataTable('#sync_job_table') ) {
- $('#sync_job_table').DataTable().columns.adjust().responsive.recalc();
- return;
- }
-
- $('#sync_job_table').DataTable({
- processing: true,
- serverSide: false,
- language: lang_datatables,
- ajax: {
- type: "GET",
- url: '/api/v1/get/syncjobs/' + encodeURIComponent(mailcow_cc_username) + '/no_log',
- dataSrc: function(data){
- console.log(data);
- $.each(data, function (i, item) {
- item.user1 = escapeHtml(item.user1);
- item.log = '<a href="#syncjobLogModal" data-bs-toggle="modal" data-syncjob-id="' + item.id + '">' + lang.open_logs + '</a>'
- if (!item.exclude > 0) {
- item.exclude = '-';
- } else {
- item.exclude = '<code>' + escapeHtml(item.exclude) + '</code>';
- }
- item.server_w_port = escapeHtml(item.user1 + '@' + item.host1 + ':' + item.port1);
- if (acl_data.syncjobs === 1) {
- item.action = '<div class="btn-group">' +
- '<a href="/edit/syncjob/' + item.id + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-syncjob" data-api-url="delete/syncjob" data-item="' + item.id + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- item.chkbox = '<input type="checkbox" data-id="syncjob" name="multi_select" value="' + item.id + '" />';
- }
- else {
- item.action = '<span>-</span>';
- item.chkbox = '<input type="checkbox" disabled />';
- }
- if (item.is_running == 1) {
- item.is_running = '<span id="active-script" class="badge fs-6 bg-success">' + lang.running + '</span>';
- } else {
- item.is_running = '<span id="inactive-script" class="badge fs-6 bg-warning">' + lang.waiting + '</span>';
- }
- if (!item.last_run > 0) {
- item.last_run = lang.waiting;
- }
- if (item.success == null) {
- item.success = '-';
- item.exit_status = '';
- } else {
- item.success = '<i class="text-' + (item.success == 1 ? 'success' : 'danger') + ' bi bi-' + (item.success == 1 ? 'check-lg' : 'x-lg') + '"></i>';
- }
- if (lang['syncjob_'+item.exit_status]) {
- item.exit_status = lang['syncjob_'+item.exit_status];
- } else if (item.success != '-') {
- item.exit_status = lang.syncjob_check_log;
- }
- item.exit_status = item.success + ' ' + item.exit_status;
- });
-
- return data;
- }
- },
- columns: [
- {
- // placeholder, so checkbox will not block child row toggle
- title: '',
- data: null,
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 1
- },
- {
- title: '',
- data: 'chkbox',
- searchable: false,
- orderable: false,
- defaultContent: '',
- responsivePriority: 2
- },
- {
- title: 'ID',
- data: 'id',
- defaultContent: '',
- responsivePriority: 3
- },
- {
- title: 'Server',
- data: 'server_w_port',
- defaultContent: ''
- },
- {
- title: lang.username,
- data: 'user1',
- defaultContent: '',
- responsivePriority: 3
- },
- {
- title: lang.last_run,
- data: 'last_run',
- defaultContent: ''
- },
- {
- title: lang.syncjob_last_run_result,
- data: 'exit_status',
- defaultContent: ''
- },
- {
- title: 'Log',
- data: 'log',
- defaultContent: ''
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>'
- }
- },
- {
- title: lang.status,
- data: 'is_running',
- defaultContent: '',
- responsivePriority: 5
- },
- {
- title: lang.encryption,
- data: 'enc1',
- defaultContent: ''
- },
- {
- title: lang.excludes,
- data: 'exclude',
- defaultContent: ''
- },
- {
- title: lang.interval + " (min)",
- data: 'mins_interval',
- defaultContent: ''
- },
- {
- title: lang.action,
- data: 'action',
- className: 'text-md-end dt-sm-head-hidden dt-body-right',
- defaultContent: '',
- responsivePriority: 5
- }
- ]
- });
- }
- function draw_app_passwd_table() {
- // just recalc width if instance already exists
- if ($.fn.DataTable.isDataTable('#app_passwd_table') ) {
- $('#app_passwd_table').DataTable().columns.adjust().responsive.recalc();
- return;
- }
-
- $('#app_passwd_table').DataTable({
- processing: true,
- serverSide: false,
- language: lang_datatables,
- ajax: {
- type: "GET",
- url: '/api/v1/get/app-passwd/all',
- dataSrc: function(data){
- console.log(data);
- $.each(data, function (i, item) {
- item.name = escapeHtml(item.name)
- item.protocols = []
- if (item.imap_access == 1) { item.protocols.push("<code>IMAP</code>"); }
- if (item.smtp_access == 1) { item.protocols.push("<code>SMTP</code>"); }
- if (item.eas_access == 1) { item.protocols.push("<code>EAS/ActiveSync</code>"); }
- if (item.dav_access == 1) { item.protocols.push("<code>DAV</code>"); }
- if (item.pop3_access == 1) { item.protocols.push("<code>POP3</code>"); }
- if (item.sieve_access == 1) { item.protocols.push("<code>Sieve</code>"); }
- item.protocols = item.protocols.join(" ")
- if (acl_data.app_passwds === 1) {
- item.action = '<div class="btn-group">' +
- '<a href="/edit/app-passwd/' + item.id + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
- '<a href="#" data-action="delete_selected" data-id="single-apppasswd" data-api-url="delete/app-passwd" data-item="' + item.id + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
- '</div>';
- item.chkbox = '<input type="checkbox" data-id="apppasswd" name="multi_select" value="' + item.id + '" />';
- }
- else {
- item.action = '<span>-</span>';
- item.chkbox = '<input type="checkbox" disabled />';
- }
- });
-
- 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: 'id',
- defaultContent: ''
- },
- {
- title: lang.app_name,
- data: 'name',
- defaultContent: ''
- },
- {
- title: lang.allowed_protocols,
- data: 'protocols',
- defaultContent: ''
- },
- {
- title: lang.active,
- data: 'active',
- defaultContent: '',
- render: function (data, type) {
- return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>'
- }
- },
- {
- title: lang.action,
- data: 'action',
- className: 'text-md-end dt-sm-head-hidden dt-body-right',
- defaultContent: ''
- }
- ]
- });
- }
- function draw_wl_policy_mailbox_table() {
- // just recalc width if instance already exists
- if ($.fn.DataTable.isDataTable('#wl_policy_mailbox_table') ) {
- $('#wl_policy_mailbox_table').DataTable().columns.adjust().responsive.recalc();
- return;
- }
-
- $('#wl_policy_mailbox_table').DataTable({
- processing: true,
- serverSide: false,
- language: lang_datatables,
- ajax: {
- type: "GET",
- url: '/api/v1/get/policy_wl_mailbox',
- dataSrc: function(data){
- console.log(data);
- $.each(data, function (i, item) {
- if (validateEmail(item.object)) {
- item.chkbox = '<input type="checkbox" data-id="policy_wl_mailbox" name="multi_select" value="' + item.prefid + '" />';
- }
- else {
- item.chkbox = '<input type="checkbox" disabled title="' + lang.spamfilter_table_domain_policy + '" />';
- }
- if (acl_data.spam_policy === 0) {
- item.chkbox = '<input type="checkbox" disabled />';
- }
- });
-
- 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.spamfilter_table_rule,
- data: 'value',
- defaultContent: ''
- },
- {
- title:'Scope',
- data: 'object',
- defaultContent: ''
- }
- ]
- });
- }
- function draw_bl_policy_mailbox_table() {
- // just recalc width if instance already exists
- if ($.fn.DataTable.isDataTable('#bl_policy_mailbox_table') ) {
- $('#bl_policy_mailbox_table').DataTable().columns.adjust().responsive.recalc();
- return;
- }
-
- $('#bl_policy_mailbox_table').DataTable({
- processing: true,
- serverSide: false,
- language: lang_datatables,
- ajax: {
- type: "GET",
- url: '/api/v1/get/policy_bl_mailbox',
- dataSrc: function(data){
- console.log(data);
- $.each(data, function (i, item) {
- if (validateEmail(item.object)) {
- item.chkbox = '<input type="checkbox" data-id="policy_bl_mailbox" name="multi_select" value="' + item.prefid + '" />';
- }
- else {
- item.chkbox = '<input type="checkbox" disabled tooltip="' + lang.spamfilter_table_domain_policy + '" />';
- }
- if (acl_data.spam_policy === 0) {
- item.chkbox = '<input type="checkbox" disabled />';
- }
- });
-
- 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.spamfilter_table_rule,
- data: 'value',
- defaultContent: ''
- },
- {
- title:'Scope',
- data: 'object',
- defaultContent: ''
- }
- ]
- });
- }
-
- // 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')));
- }
- })
-
- // Sieve data modal
- $('#userFilterModal').on('show.bs.modal', function(e) {
- $('#user_sieve_filter').text(lang.loading);
- $.ajax({
- dataType: 'json',
- url: '/api/v1/get/active-user-sieve/' + encodeURIComponent(mailcow_cc_username),
- jsonp: false,
- error: function () {
- console.log('Cannot get active sieve script');
- },
- complete: function (data) {
- if (data.responseText == '{}') {
- $('#user_sieve_filter').text(lang.no_active_filter);
- } else {
- $('#user_sieve_filter').text(JSON.parse(data.responseText));
- }
- }
- })
- });
- $('#userFilterModal').on('hidden.bs.modal', function () {
- $('#user_sieve_filter').text(lang.loading);
- });
-
- // 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);
- });
- }
-
- // Load only if the tab is visible
- onVisible("[id^=tla_table]", () => draw_tla_table());
- onVisible("[id^=bl_policy_mailbox_table]", () => draw_bl_policy_mailbox_table());
- onVisible("[id^=wl_policy_mailbox_table]", () => draw_wl_policy_mailbox_table());
- onVisible("[id^=sync_job_table]", () => draw_sync_job_table());
- onVisible("[id^=app_passwd_table]", () => draw_app_passwd_table());
- last_logins('get');
-});
+// 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<r.length;)a=(t=r.charCodeAt(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<r.length;)t=this._keyStr.indexOf(r.charAt(d++))<<2|(a=this._keyStr.indexOf(r.charAt(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;e<r.length;e++){var o=r.charCodeAt(e);o<128?t+=String.fromCharCode(o):o>127&&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;e<r.length;)(o=r.charCodeAt(e))<128?(t+=String.fromCharCode(o),e++):o>191&&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}};
+$(document).ready(function() {
+ // Spam score slider
+ var spam_slider = $('#spam_score')[0];
+ if (typeof spam_slider !== 'undefined') {
+ noUiSlider.create(spam_slider, {
+ start: user_spam_score,
+ connect: [true, true, true],
+ range: {
+ 'min': [0], //stepsize is 50.000
+ '50%': [10],
+ '70%': [20, 5],
+ '80%': [50, 10],
+ '90%': [100, 100],
+ '95%': [1000, 1000],
+ 'max': [5000]
+ },
+ });
+ var connect = spam_slider.querySelectorAll('.noUi-connect');
+ var classes = ['c-1-color', 'c-2-color', 'c-3-color'];
+ for (var i = 0; i < connect.length; i++) {
+ connect[i].classList.add(classes[i]);
+ }
+ spam_slider.noUiSlider.on('update', function (values, handle) {
+ $('.spam-ham-score').text('< ' + Math.round(values[0] * 10) / 10);
+ $('.spam-spam-score').text(Math.round(values[0] * 10) / 10 + ' - ' + Math.round(values[1] * 10) / 10);
+ $('.spam-reject-score').text('> ' + Math.round(values[1] * 10) / 10);
+ $('#spam_score_value').val((Math.round(values[0] * 10) / 10) + ',' + (Math.round(values[1] * 10) / 10));
+ });
+ }
+ // syncjobLogModal
+ $('#syncjobLogModal').on('show.bs.modal', function(e) {
+ var syncjob_id = $(e.relatedTarget).data('syncjob-id');
+ $.ajax({
+ url: '/inc/ajax/syncjob_logs.php',
+ data: { id: syncjob_id },
+ dataType: 'text',
+ success: function(data){
+ $(e.currentTarget).find('#logText').text(data);
+ },
+ error: function(xhr, status, error) {
+ $(e.currentTarget).find('#logText').text(xhr.responseText);
+ }
+ });
+ });
+ $(".arrow-toggle").on('click', function(e) { e.preventDefault(); $(this).find('.arrow').toggleClass("animation"); });
+ $("#pushover_delete").click(function() { return confirm(lang.delete_ays); });
+
+});
+jQuery(function($){
+ // http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery
+ var entityMap = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": ''',
+ '/': '/',
+ '`': '`',
+ '=': '='
+ };
+ function escapeHtml(string) {
+ return String(string).replace(/[&<>"'`=\/]/g, function (s) {
+ return entityMap[s];
+ });
+ }
+ // 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 unix_time_format(tm) {
+ var date = new Date(tm ? tm * 1000 : 0);
+ return date.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
+ }
+ acl_data = JSON.parse(acl);
+
+ $('.clear-last-logins').on('click', function () {if (confirm(lang.delete_ays)) {last_logins('reset');}})
+ $(".login-history").on('click', function(e) {e.preventDefault(); last_logins('get', $(this).data('days'));$(this).addClass('active').siblings().removeClass('active');});
+
+ function last_logins(action, days = 7) {
+ if (action == 'get') {
+ $('.last-login').html('<i class="bi bi-hourglass"></i>' + lang.waiting);
+ $.ajax({
+ dataType: 'json',
+ url: '/api/v1/get/last-login/' + encodeURIComponent(mailcow_cc_username) + '/' + days,
+ jsonp: false,
+ error: function () {
+ console.log('error reading last logins');
+ },
+ success: function (data) {
+ $('.last-login').html();
+ if (data.ui.time) {
+ $('.last-login').html('<i class="bi bi-person-fill"></i> ' + lang.last_ui_login + ': ' + unix_time_format(data.ui.time));
+ } else {
+ $('.last-login').text(lang.no_last_login);
+ }
+ if (data.sasl) {
+ $('.last-login').append('<ul class="list-group">');
+ $.each(data.sasl, function (i, item) {
+ var datetime = new Date(item.datetime.replace(/-/g, "/"));
+ var local_datetime = datetime.toLocaleDateString(undefined, {year: "numeric", month: "2-digit", day: "2-digit", hour: "2-digit", minute: "2-digit", second: "2-digit"});
+ var service = '<div class="badge fs-6 bg-secondary">' + item.service.toUpperCase() + '</div>';
+ var app_password = item.app_password ? ' <a href="/edit/app-passwd/' + item.app_password + '"><i class="bi bi-app-indicator"></i> ' + escapeHtml(item.app_password_name || "App") + '</a>' : '';
+ var real_rip = item.real_rip.startsWith("Web") ? item.real_rip : '<a href="https://bgp.he.net/ip/' + item.real_rip + '" target="_blank">' + item.real_rip + "</a>";
+ var ip_location = item.location ? ' <span class="flag-icon flag-icon-' + item.location.toLowerCase() + '"></span>' : '';
+ var ip_data = real_rip + ip_location + app_password;
+ $(".last-login").append('<li class="list-group-item">' + local_datetime + " " + service + " " + lang.from + " " + ip_data + "</li>");
+ })
+ $('.last-login').append('</ul>');
+ }
+ }
+ })
+ } else if (action == 'reset') {
+ $.ajax({
+ dataType: 'json',
+ url: '/api/v1/get/reset-last-login/' + encodeURIComponent(mailcow_cc_username),
+ jsonp: false,
+ error: function () {
+ console.log('cannot reset last logins');
+ },
+ success: function (data) {
+ last_logins('get');
+ }
+ })
+ }
+ }
+
+
+ function createSortableDate(td, cellData, date_string = false) {
+ if (date_string)
+ var date = new Date(cellData);
+ else
+ var date = new Date(cellData ? cellData * 1000 : 0);
+
+ var timestamp = date.getTime();
+ $(td).attr({
+ "data-order": timestamp,
+ "data-sort": timestamp
+ });
+ $(td).html(date.toLocaleDateString(LOCALE, DATETIME_FORMAT));
+ }
+ function draw_tla_table() {
+ // just recalc width if instance already exists
+ if ($.fn.DataTable.isDataTable('#tla_table') ) {
+ $('#tla_table').DataTable().columns.adjust().responsive.recalc();
+ return;
+ }
+
+ $('#tla_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,
+ order: [[4, 'desc']],
+ ajax: {
+ type: "GET",
+ url: "/api/v1/get/time_limited_aliases",
+ dataSrc: function(data){
+ console.log(data);
+ $.each(data, function (i, item) {
+ if (acl_data.spam_alias === 1) {
+ item.action = '<div class="btn-group">' +
+ '<a href="#" data-action="delete_selected" data-id="single-tla" data-api-url="delete/time_limited_alias" data-item="' + encodeURIComponent(item.address) + '" class="btn btn-xs btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="tla" name="multi_select" value="' + encodeURIComponent(item.address) + '" />';
+ item.address = escapeHtml(item.address);
+ }
+ else {
+ item.chkbox = '<input type="checkbox" class="form-check-input" disabled />';
+ item.action = '<span>-</span>';
+ }
+ });
+
+ 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: lang.alias,
+ data: 'address',
+ defaultContent: ''
+ },
+ {
+ title: lang.alias_valid_until,
+ data: 'validity',
+ defaultContent: '',
+ createdCell: function(td, cellData) {
+ createSortableDate(td, cellData)
+ }
+ },
+ {
+ title: lang.created_on,
+ data: 'created',
+ defaultContent: '',
+ createdCell: function(td, cellData) {
+ createSortableDate(td, cellData, true)
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-text-right',
+ defaultContent: ''
+ }
+ ]
+ });
+ }
+ function draw_sync_job_table() {
+ // just recalc width if instance already exists
+ if ($.fn.DataTable.isDataTable('#sync_job_table') ) {
+ $('#sync_job_table').DataTable().columns.adjust().responsive.recalc();
+ return;
+ }
+
+ $('#sync_job_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/syncjobs/' + encodeURIComponent(mailcow_cc_username) + '/no_log',
+ dataSrc: function(data){
+ console.log(data);
+ $.each(data, function (i, item) {
+ item.user1 = escapeHtml(item.user1);
+ item.log = '<a href="#syncjobLogModal" data-bs-toggle="modal" data-syncjob-id="' + item.id + '">' + lang.open_logs + '</a>'
+ if (!item.exclude > 0) {
+ item.exclude = '-';
+ } else {
+ item.exclude = '<code>' + escapeHtml(item.exclude) + '</code>';
+ }
+ item.server_w_port = escapeHtml(item.user1 + '@' + item.host1 + ':' + item.port1);
+ if (acl_data.syncjobs === 1) {
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit/syncjob/' + item.id + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-syncjob" data-api-url="delete/syncjob" data-item="' + item.id + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="syncjob" name="multi_select" value="' + item.id + '" />';
+ }
+ else {
+ item.action = '<span>-</span>';
+ item.chkbox = '<input type="checkbox" class="form-check-input" disabled />';
+ }
+ if (item.is_running == 1) {
+ item.is_running = '<span id="active-script" class="badge fs-6 bg-success">' + lang.running + '</span>';
+ } else {
+ item.is_running = '<span id="inactive-script" class="badge fs-6 bg-warning">' + lang.waiting + '</span>';
+ }
+ if (!item.last_run > 0) {
+ item.last_run = lang.waiting;
+ }
+ if (item.success == null) {
+ item.success = '-';
+ item.exit_status = '';
+ } else {
+ item.success = '<i class="text-' + (item.success == 1 ? 'success' : 'danger') + ' bi bi-' + (item.success == 1 ? 'check-lg' : 'x-lg') + '"></i>';
+ }
+ if (lang['syncjob_'+item.exit_status]) {
+ item.exit_status = lang['syncjob_'+item.exit_status];
+ } else if (item.success != '-') {
+ item.exit_status = lang.syncjob_check_log;
+ }
+ item.exit_status = item.success + ' ' + item.exit_status;
+ });
+
+ return data;
+ }
+ },
+ columns: [
+ {
+ // placeholder, so checkbox will not block child row toggle
+ title: '',
+ data: null,
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 1
+ },
+ {
+ title: '',
+ data: 'chkbox',
+ searchable: false,
+ orderable: false,
+ defaultContent: '',
+ responsivePriority: 2
+ },
+ {
+ title: 'ID',
+ data: 'id',
+ defaultContent: '',
+ responsivePriority: 3
+ },
+ {
+ title: 'Server',
+ data: 'server_w_port',
+ defaultContent: ''
+ },
+ {
+ title: lang.username,
+ data: 'user1',
+ defaultContent: '',
+ responsivePriority: 3
+ },
+ {
+ title: lang.last_run,
+ data: 'last_run',
+ defaultContent: ''
+ },
+ {
+ title: lang.syncjob_last_run_result,
+ data: 'exit_status',
+ defaultContent: ''
+ },
+ {
+ title: 'Log',
+ data: 'log',
+ defaultContent: ''
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>'
+ }
+ },
+ {
+ title: lang.status,
+ data: 'is_running',
+ defaultContent: '',
+ responsivePriority: 5
+ },
+ {
+ title: lang.encryption,
+ data: 'enc1',
+ defaultContent: ''
+ },
+ {
+ title: lang.excludes,
+ data: 'exclude',
+ defaultContent: ''
+ },
+ {
+ title: lang.interval + " (min)",
+ data: 'mins_interval',
+ defaultContent: ''
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-text-right',
+ defaultContent: '',
+ responsivePriority: 5
+ }
+ ]
+ });
+ }
+ function draw_app_passwd_table() {
+ // just recalc width if instance already exists
+ if ($.fn.DataTable.isDataTable('#app_passwd_table') ) {
+ $('#app_passwd_table').DataTable().columns.adjust().responsive.recalc();
+ return;
+ }
+
+ $('#app_passwd_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/app-passwd/all',
+ dataSrc: function(data){
+ console.log(data);
+ $.each(data, function (i, item) {
+ item.name = escapeHtml(item.name)
+ item.protocols = []
+ if (item.imap_access == 1) { item.protocols.push("<code>IMAP</code>"); }
+ if (item.smtp_access == 1) { item.protocols.push("<code>SMTP</code>"); }
+ if (item.eas_access == 1) { item.protocols.push("<code>EAS/ActiveSync</code>"); }
+ if (item.dav_access == 1) { item.protocols.push("<code>DAV</code>"); }
+ if (item.pop3_access == 1) { item.protocols.push("<code>POP3</code>"); }
+ if (item.sieve_access == 1) { item.protocols.push("<code>Sieve</code>"); }
+ item.protocols = item.protocols.join(" ")
+ if (acl_data.app_passwds === 1) {
+ item.action = '<div class="btn-group">' +
+ '<a href="/edit/app-passwd/' + item.id + '" class="btn btn-xs btn-xs-half btn-secondary"><i class="bi bi-pencil-fill"></i> ' + lang.edit + '</a>' +
+ '<a href="#" data-action="delete_selected" data-id="single-apppasswd" data-api-url="delete/app-passwd" data-item="' + item.id + '" class="btn btn-xs btn-xs-half btn-danger"><i class="bi bi-trash"></i> ' + lang.remove + '</a>' +
+ '</div>';
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="apppasswd" name="multi_select" value="' + item.id + '" />';
+ }
+ else {
+ item.action = '<span>-</span>';
+ item.chkbox = '<input type="checkbox" class="form-check-input" disabled />';
+ }
+ });
+
+ 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: 'id',
+ defaultContent: ''
+ },
+ {
+ title: lang.app_name,
+ data: 'name',
+ defaultContent: ''
+ },
+ {
+ title: lang.allowed_protocols,
+ data: 'protocols',
+ defaultContent: ''
+ },
+ {
+ title: lang.active,
+ data: 'active',
+ defaultContent: '',
+ render: function (data, type) {
+ return 1==data?'<i class="bi bi-check-lg"></i>':0==data&&'<i class="bi bi-x-lg"></i>'
+ }
+ },
+ {
+ title: lang.action,
+ data: 'action',
+ className: 'dt-sm-head-hidden dt-text-right',
+ defaultContent: ''
+ }
+ ]
+ });
+ }
+ function draw_wl_policy_mailbox_table() {
+ // just recalc width if instance already exists
+ if ($.fn.DataTable.isDataTable('#wl_policy_mailbox_table') ) {
+ $('#wl_policy_mailbox_table').DataTable().columns.adjust().responsive.recalc();
+ return;
+ }
+
+ $('#wl_policy_mailbox_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_mailbox',
+ dataSrc: function(data){
+ console.log(data);
+ $.each(data, function (i, item) {
+ if (validateEmail(item.object)) {
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="policy_wl_mailbox" name="multi_select" value="' + item.prefid + '" />';
+ }
+ else {
+ item.chkbox = '<input type="checkbox" class="form-check-input" disabled title="' + lang.spamfilter_table_domain_policy + '" />';
+ }
+ if (acl_data.spam_policy === 0) {
+ item.chkbox = '<input type="checkbox" class="form-check-input" disabled />';
+ }
+ });
+
+ 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.spamfilter_table_rule,
+ data: 'value',
+ defaultContent: ''
+ },
+ {
+ title:'Scope',
+ data: 'object',
+ defaultContent: ''
+ }
+ ]
+ });
+ }
+ function draw_bl_policy_mailbox_table() {
+ // just recalc width if instance already exists
+ if ($.fn.DataTable.isDataTable('#bl_policy_mailbox_table') ) {
+ $('#bl_policy_mailbox_table').DataTable().columns.adjust().responsive.recalc();
+ return;
+ }
+
+ $('#bl_policy_mailbox_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_mailbox',
+ dataSrc: function(data){
+ console.log(data);
+ $.each(data, function (i, item) {
+ if (validateEmail(item.object)) {
+ item.chkbox = '<input type="checkbox" class="form-check-input" data-id="policy_bl_mailbox" name="multi_select" value="' + item.prefid + '" />';
+ }
+ else {
+ item.chkbox = '<input type="checkbox" class="form-check-input" disabled tooltip="' + lang.spamfilter_table_domain_policy + '" />';
+ }
+ if (acl_data.spam_policy === 0) {
+ item.chkbox = '<input type="checkbox" class="form-check-input" disabled />';
+ }
+ });
+
+ 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.spamfilter_table_rule,
+ data: 'value',
+ defaultContent: ''
+ },
+ {
+ title:'Scope',
+ data: 'object',
+ defaultContent: ''
+ }
+ ]
+ });
+ }
+
+ // 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')));
+ }
+ })
+
+ // Sieve data modal
+ $('#userFilterModal').on('show.bs.modal', function(e) {
+ $('#user_sieve_filter').text(lang.loading);
+ $.ajax({
+ dataType: 'json',
+ url: '/api/v1/get/active-user-sieve/' + encodeURIComponent(mailcow_cc_username),
+ jsonp: false,
+ error: function () {
+ console.log('Cannot get active sieve script');
+ },
+ complete: function (data) {
+ if (data.responseText == '{}') {
+ $('#user_sieve_filter').text(lang.no_active_filter);
+ } else {
+ $('#user_sieve_filter').text(JSON.parse(data.responseText));
+ }
+ }
+ })
+ });
+ $('#userFilterModal').on('hidden.bs.modal', function () {
+ $('#user_sieve_filter').text(lang.loading);
+ });
+
+ // 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);
+ });
+ }
+
+ // Load only if the tab is visible
+ onVisible("[id^=tla_table]", () => draw_tla_table());
+ onVisible("[id^=bl_policy_mailbox_table]", () => draw_bl_policy_mailbox_table());
+ onVisible("[id^=wl_policy_mailbox_table]", () => draw_wl_policy_mailbox_table());
+ onVisible("[id^=sync_job_table]", () => draw_sync_job_table());
+ onVisible("[id^=app_passwd_table]", () => draw_app_passwd_table());
+ last_logins('get');
+});