Browse Source

A lot of changes... still not finished, use with caution.
Edit actions can be done with the internal API, trying to get rid of edit and add files

andryyy 8 years ago
parent
commit
14a9a1c616

+ 23 - 12
data/web/add.php

@@ -21,6 +21,9 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 ?>
 				<h4><?=$lang['add']['domain'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+          <input type="hidden" value="0" name="active">
+          <input type="hidden" value="0" name="backupmx">
+          <input type="hidden" value="0" name="relay_all_recipients">
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="domain"><?=$lang['add']['domain'];?>:</label>
 						<div class="col-sm-10">
@@ -61,9 +64,9 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 						<label class="control-label col-sm-2"><?=$lang['add']['backup_mx_options'];?></label>
 						<div class="col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="backupmx"> <?=$lang['add']['relay_domain'];?></label>
+							<label><input type="checkbox" value="1" name="backupmx"> <?=$lang['add']['relay_domain'];?></label>
 							<br />
-							<label><input type="checkbox" name="relay_all_recipients"> <?=$lang['add']['relay_all'];?></label>
+							<label><input type="checkbox" value="1" name="relay_all_recipients"> <?=$lang['add']['relay_all'];?></label>
 							<p><?=$lang['add']['relay_all_info'];?></p>
 							</div>
 						</div>
@@ -71,7 +74,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
+							<label><input type="checkbox" value="1" name="active" checked> <?=$lang['add']['active'];?></label>
 							</div>
 						</div>
 					</div>
@@ -89,6 +92,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 				<h4><?=$lang['add']['alias'];?></h4>
 				<p><?=$lang['add']['alias_spf_fail'];?></p>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+          <input type="hidden" value="0" name="active">
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="address"><?=$lang['add']['alias_address'];?></label>
 						<div class="col-sm-10">
@@ -106,7 +110,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
+							<label><input type="checkbox" value="1" name="active" checked> <?=$lang['add']['active'];?></label>
 							</div>
 						</div>
 					</div>
@@ -122,6 +126,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 	?>
 				<h4><?=$lang['add']['alias_domain'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+          <input type="hidden" value="0" name="active">
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="alias_domain"><?=$lang['add']['alias_domain'];?></label>
 						<div class="col-sm-10">
@@ -144,7 +149,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
+							<label><input type="checkbox" value="1" name="active" checked> <?=$lang['add']['active'];?></label>
 							</div>
 						</div>
 					</div>
@@ -160,6 +165,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 	?>
 				<h4><?=$lang['add']['mailbox'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+          <input type="hidden" value="0" name="active">
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="local_part"><?=$lang['add']['mailbox_username'];?></label>
 						<div class="col-sm-10">
@@ -207,7 +213,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
+							<label><input type="checkbox" value="1" name="active" checked> <?=$lang['add']['active'];?></label>
 							</div>
 						</div>
 					</div>
@@ -223,6 +229,8 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 	?>
 				<h4><?=$lang['add']['resource'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+          <input type="hidden" value="0" name="active">
+          <input type="hidden" value="0" name="multiple_bookings">
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="description"><?=$lang['add']['description'];?></label>
 						<div class="col-sm-10">
@@ -254,14 +262,14 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
+							<label><input type="checkbox" value="1" name="active" checked> <?=$lang['add']['active'];?></label>
 							</div>
 						</div>
 					</div>
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="multiple_bookings" checked> <?=$lang['add']['multiple_bookings'];?></label>
+							<label><input type="checkbox" value="1" name="multiple_bookings" checked> <?=$lang['add']['multiple_bookings'];?></label>
 							</div>
 						</div>
 					</div>
@@ -285,6 +293,9 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
 				<h4><?=$lang['add']['syncjob'];?></h4>
 				<p><?=$lang['add']['syncjob_hint'];?></p>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+          <input type="hidden" value="0" name="active">
+          <input type="hidden" value="0" name="delete1">
+          <input type="hidden" value="0" name="delete2duplicates">
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="host1"><?=$lang['add']['hostname'];?></label>
 						<div class="col-sm-10">
@@ -346,27 +357,27 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="delete2duplicates" checked> <?=$lang['add']['delete2duplicates'];?></label>
+							<label><input type="checkbox" value="1" name="delete2duplicates" checked> <?=$lang['add']['delete2duplicates'];?></label>
 							</div>
 						</div>
 					</div>
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="delete1"> <?=$lang['add']['delete1'];?></label>
+							<label><input type="checkbox" value="1" name="delete1"> <?=$lang['add']['delete1'];?></label>
 							</div>
 						</div>
 					</div>
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" checked> <?=$lang['add']['active'];?></label>
+							<label><input type="checkbox" value="1" name="active" checked> <?=$lang['add']['active'];?></label>
 							</div>
 						</div>
 					</div>
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
-							<button type="submit" name="add_syncjob" value="1" class="btn btn-success "><?=$lang['add']['save'];?></button>
+							<button type="submit" name="add_syncjob" class="btn btn-success "><?=$lang['add']['save'];?></button>
 						</div>
 					</div>
 				</form>

+ 31 - 33
data/web/admin.php

@@ -100,6 +100,7 @@ $tfa_data = get_tfa();
           <small>
           <legend><?=$lang['admin']['add_domain_admin'];?></legend>
           <form class="form-horizontal" role="form" method="post">
+            <input type="hidden" value="0" name="active">
             <div class="form-group">
               <label class="control-label col-sm-2" for="username"><?=$lang['admin']['username'];?>:</label>
               <div class="col-sm-10">
@@ -134,7 +135,7 @@ $tfa_data = get_tfa();
             <div class="form-group">
               <div class="col-sm-offset-2 col-sm-10">
                 <div class="checkbox">
-                <label><input type="checkbox" name="active" checked> <?=$lang['admin']['active'];?></label>
+                <label><input type="checkbox" value="1" name="active" checked> <?=$lang['admin']['active'];?></label>
                 </div>
               </div>
             </div>
@@ -155,36 +156,39 @@ $tfa_data = get_tfa();
     <div class="panel panel-default">
       <div class="panel-heading"><?=$lang['admin']['dkim_keys'];?></div>
       <div class="panel-body">
-      <form class="form-inline" method="post" data-id="dkimkeys">
+        <div class="mass-actions-admin">
+          <div class="btn-group btn-group-sm">
+            <button type="button" id="toggle_multi_select_all" data-id="dkim" class="btn btn-default"><?=$lang['mailbox']['toggle_all'];?></button>
+            <button type="button" id="delete_selected" name="delete_selected" data-id="dkim" data-api-url="delete/dkim" class="btn btn-danger"><?=$lang['admin']['remove'];?></button>
+          </div>
+        </div>
         <?php
         foreach(mailbox_get_domains() as $domain) {
             if (!empty($dkim = dkim_get_key_details($domain))) {
           ?>
             <div class="row">
-              <div class="col-xs-3">
+              <div class="col-xs-1"><input type="checkbox" data-id="dkim" name="multi_select" value="<?=$domain;?>" /></div>
+              <div class="col-xs-2">
                 <p>Domain: <strong><?=htmlspecialchars($domain);?></strong><br />
                   <span class="label label-success"><?=$lang['admin']['dkim_key_valid'];?></span>
                   <span class="label label-primary">Selector '<?=$dkim['dkim_selector'];?>'</span>
                   <span class="label label-info"><?=$dkim['length'];?> bit</span>
                 </p>
               </div>
-              <div class="col-xs-8">
+              <div class="col-xs-9">
                   <pre><?=$dkim['dkim_txt'];?></pre>
               </div>
-              <div class="col-xs-1">
-                <span style="cursor:pointer" data-dkim-domain="<?=$domain;?>" data-dkim-selector="<?=$dkim['dkim_selector'];?>" id="delete_dkim_key" class="text-danger glyphicon glyphicon-remove"></span></a>
-              </div>
             </div>
           <?php
           }
           else {
           ?>
           <div class="row">
-            <div class="col-xs-3">
+              <div class="col-xs-1"><input type="checkbox" data-id="dkim" name="multi_select" value="<?=$domain;?>" disabled /></div>
+            <div class="col-xs-2">
               <p>Domain: <strong><?=htmlspecialchars($domain);?></strong><br /><span class="label label-danger"><?=$lang['admin']['dkim_key_missing'];?></span></p>
             </div>
-            <div class="col-xs-8"><pre>-</pre></div>
-            <div class="col-xs-1">&nbsp;</div>
+            <div class="col-xs-9"><pre>-</pre></div>
           </div>
           <?php
           }
@@ -192,30 +196,28 @@ $tfa_data = get_tfa();
             if (!empty($dkim = dkim_get_key_details($alias_domain))) {
             ?>
               <div class="row">
-                <div class="col-xs-offset-1 col-xs-2">
+              <div class="col-xs-1"><input type="checkbox" data-id="dkim" name="multi_select" value="<?=$alias_domain;?>" /></div>
+                <div class="col-xs-1 col-xs-offset-1">
                   <p><small>↳ Alias-Domain: <strong><?=htmlspecialchars($alias_domain);?></strong><br /></small>
                     <span class="label label-success"><?=$lang['admin']['dkim_key_valid'];?></span>
                     <span class="label label-primary">Selector '<?=$dkim['dkim_selector'];?>'</span>
                     <span class="label label-info"><?=$dkim['length'];?> bit</span>
                 </p>
                 </div>
-                <div class="col-xs-8">
+                <div class="col-xs-9">
                   <pre><?=$dkim['dkim_txt'];?></pre>
                 </div>
-                <div class="col-xs-1">
-                  <span style="cursor:pointer" data-dkim-domain="<?=$domain;?>" data-dkim-selector="<?=$dkim['dkim_selector'];?>" id="delete_dkim_key" class="text-danger glyphicon glyphicon-remove"></span></a>
-                </div>
               </div>
             <?php
             }
             else {
             ?>
             <div class="row">
-              <div class="col-xs-2 col-xs-offset-1">
+              <div class="col-xs-1"><input type="checkbox" data-id="dkim" name="multi_select" value="<?=$domain;?>" disabled /></div>
+              <div class="col-xs-1 col-xs-offset-1">
                 <p><small>↳ Alias-Domain: <strong><?=htmlspecialchars($alias_domain);?></strong><br /></small><span class="label label-danger"><?=$lang['admin']['dkim_key_missing'];?></span></p>
               </div>
-            <div class="col-xs-8"><pre>-</pre></div>
-            <div class="col-xs-1">&nbsp;</div>
+            <div class="col-xs-9"><pre>-</pre></div>
             </div>
             <?php
             }
@@ -225,25 +227,22 @@ $tfa_data = get_tfa();
           if (!empty($dkim = dkim_get_key_details($blind))) {
           ?>
             <div class="row">
-              <div class="col-xs-3">
+              <div class="col-xs-1"><input type="checkbox" data-id="dkim" name="multi_select" value="<?=$blind;?>" /></div>
+              <div class="col-xs-2">
                 <p>Domain: <strong><?=htmlspecialchars($blind);?></strong><br />
                   <span class="label label-warning"><?=$lang['admin']['dkim_key_unused'];?></span>
                   <span class="label label-primary">Selector '<?=$dkim['dkim_selector'];?>'</span>
                   <span class="label label-info"><?=$dkim['length'];?> bit</span>
                 </p>
                 </div>
-                <div class="col-xs-8">
+                <div class="col-xs-9">
                   <pre><?=$dkim['dkim_txt'];?></pre>
                 </div>
-                <div class="col-xs-1">
-                  <span style="cursor:pointer" data-dkim-domain="<?=$blind;?>" data-dkim-selector="<?=$dkim['dkim_selector'];?>" id="delete_dkim_key" class="text-danger glyphicon glyphicon-remove"></span></a>
-                </div>
             </div>
           <?php
           }
         }
         ?>
-        </form>
 
         <legend style="margin-top:40px"><?=$lang['admin']['dkim_add_key'];?></legend>
         <form class="form-inline" role="form" method="post">
@@ -270,21 +269,20 @@ $tfa_data = get_tfa();
       <div class="panel-heading"><?=$lang['admin']['forwarding_hosts'];?></div>
       <div class="panel-body">
         <p style="margin-bottom:40px"><?=$lang['admin']['forwarding_hosts_hint'];?></p>
-        <form method="post" data-id="fwdhosts">
-        <div class="btn-group btn-group-sm">
-          <button type="button" id="toggle_multi_select_all" data-form-id="fwdhosts" class="btn btn-default">Toggle all</button>
-          <button type="button" id="delete_fwdhosts" name="delete_fwdhosts" class="btn btn-danger"><?=$lang['admin']['remove'];?></button>
+        <div class="mass-actions-admin">
+          <div class="btn-group btn-group-sm">
+            <button type="button" id="toggle_multi_select_all" data-id="fwdhosts" class="btn btn-default"><?=$lang['mailbox']['toggle_all'];?></button>
+            <button type="button" id="delete_selected" name="delete_selected" data-id="fwdhosts" data-api-url="delete/fwdhost" class="btn btn-danger"><?=$lang['admin']['remove'];?></button>
+          </div>
         </div>
-        <hr >
         <div class="table-responsive">
-            <table class="table table-striped" id="forwardinghoststable"></table>
-          </div>
-        </form>
+          <table class="table table-striped" id="forwardinghoststable"></table>
+        </div>
         <legend><?=$lang['admin']['add_forwarding_host'];?></legend>
         <p class="help-block"><?=$lang['admin']['forwarding_hosts_add_hint'];?></p>
         <form class="form-inline" role="form" method="post">
           <div class="form-group">
-            <label for="hostname"><?=$lang['edit']['host'];?></label>
+            <label for="hostname"><?=$lang['admin']['host'];?></label>
             <input class="form-control" id="hostname" name="hostname" placeholder="example.org" required>
           </div>
           <div class="form-group">

+ 3 - 12
data/web/css/mailbox.css

@@ -13,21 +13,12 @@ table.footable>tbody>tr.footable-empty>td {
 }
 .footer-add-item {
   display:block;
+  text-align: center;
+  font-style: italic;
   padding: 10px;
   background: #F5F5F5;
 }
-.mass-each-action {
-  padding: 0 3px 0 3px;
-  user-select: none;
-}
-.mass-actions {
-  user-select: none;
-  padding:10px;
-}
-.mass-select-all {
-  cursor:pointer;
-  color:#555;
-}
+
 #alias_table {
   cursor:pointer;
 }

+ 9 - 1
data/web/css/mailcow.css

@@ -62,4 +62,12 @@ body.modal-open {
   min-width: 350px;
   max-width: 550px;
   z-index: 2000;
-}
+}
+.mass-actions-mailbox {
+  user-select: none;
+  padding:10px 0 10px 10px;
+}
+.mass-actions-admin {
+  user-select: none;
+  padding:10px 0 10px 0;
+}

+ 0 - 650
data/web/css/noty.css

@@ -1,650 +0,0 @@
-.noty_layout_mixin, #noty_layout__top, #noty_layout__topLeft, #noty_layout__topCenter, #noty_layout__topRight, #noty_layout__bottom, #noty_layout__bottomLeft, #noty_layout__bottomCenter, #noty_layout__bottomRight, #noty_layout__center, #noty_layout__centerLeft, #noty_layout__centerRight {
-  position: fixed;
-  margin: 0;
-  padding: 0;
-  z-index: 9999999;
-  -webkit-transform: translateZ(0) scale(1, 1);
-          transform: translateZ(0) scale(1, 1);
-  -webkit-backface-visibility: hidden;
-          backface-visibility: hidden;
-  -webkit-font-smoothing: subpixel-antialiased;
-  filter: blur(0);
-  -webkit-filter: blur(0);
-  max-width: 90%; }
-
-#noty_layout__top {
-  top: 0;
-  left: 5%;
-  width: 90%; }
-
-#noty_layout__topLeft {
-  top: 20px;
-  left: 20px;
-  width: 325px; }
-
-#noty_layout__topCenter {
-  top: 5%;
-  left: 50%;
-  width: 325px;
-  -webkit-transform: translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
-          transform: translate(calc(-50% - .5px)) translateZ(0) scale(1, 1); }
-
-#noty_layout__topRight {
-  top: 20px;
-  right: 20px;
-  width: 325px; }
-
-#noty_layout__bottom {
-  bottom: 0;
-  left: 5%;
-  width: 90%; }
-
-#noty_layout__bottomLeft {
-  bottom: 20px;
-  left: 20px;
-  width: 325px; }
-
-#noty_layout__bottomCenter {
-  bottom: 5%;
-  left: 50%;
-  width: 325px;
-  -webkit-transform: translate(-webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
-          transform: translate(calc(-50% - .5px)) translateZ(0) scale(1, 1); }
-
-#noty_layout__bottomRight {
-  bottom: 20px;
-  right: 20px;
-  width: 325px; }
-
-#noty_layout__center {
-  top: 50%;
-  left: 50%;
-  width: 325px;
-  -webkit-transform: translate(-webkit-calc(-50% - .5px), -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
-          transform: translate(calc(-50% - .5px), calc(-50% - .5px)) translateZ(0) scale(1, 1); }
-
-#noty_layout__centerLeft {
-  top: 50%;
-  left: 20px;
-  width: 325px;
-  -webkit-transform: translate(0, -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
-          transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); }
-
-#noty_layout__centerRight {
-  top: 50%;
-  right: 20px;
-  width: 325px;
-  -webkit-transform: translate(0, -webkit-calc(-50% - .5px)) translateZ(0) scale(1, 1);
-          transform: translate(0, calc(-50% - .5px)) translateZ(0) scale(1, 1); }
-
-.noty_progressbar {
-  display: none; }
-
-.noty_has_timeout .noty_progressbar {
-  display: block;
-  position: absolute;
-  left: 0;
-  bottom: 0;
-  height: 3px;
-  width: 100%;
-  background-color: #646464;
-  opacity: 0.2;
-  filter: alpha(opacity=10); }
-
-.noty_bar {
-  -webkit-backface-visibility: hidden;
-  -webkit-transform: translate(0, 0) translateZ(0) scale(1, 1);
-  -ms-transform: translate(0, 0) scale(1, 1);
-      transform: translate(0, 0) scale(1, 1);
-  -webkit-font-smoothing: subpixel-antialiased;
-  overflow: hidden; }
-
-.noty_effects_open {
-  opacity: 0;
-  -webkit-transform: translate(50%);
-      -ms-transform: translate(50%);
-          transform: translate(50%);
-  -webkit-animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
-          animation: noty_anim_in 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
-  -webkit-animation-fill-mode: forwards;
-          animation-fill-mode: forwards; }
-
-.noty_effects_close {
-  -webkit-animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
-          animation: noty_anim_out 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55);
-  -webkit-animation-fill-mode: forwards;
-          animation-fill-mode: forwards; }
-
-.noty_fix_effects_height {
-  -webkit-animation: noty_anim_height 75ms ease-out;
-          animation: noty_anim_height 75ms ease-out; }
-
-.noty_close_with_click {
-  cursor: pointer; }
-
-.noty_close_button {
-  position: absolute;
-  top: 2px;
-  right: 2px;
-  font-weight: bold;
-  width: 20px;
-  height: 20px;
-  text-align: center;
-  line-height: 20px;
-  background-color: rgba(0, 0, 0, 0.05);
-  border-radius: 2px;
-  cursor: pointer;
-  -webkit-transition: all .2s ease-out;
-  transition: all .2s ease-out; }
-
-.noty_close_button:hover {
-  background-color: rgba(0, 0, 0, 0.1); }
-
-.noty_modal {
-  position: fixed;
-  width: 100%;
-  height: 100%;
-  background-color: #000;
-  z-index: 10000;
-  opacity: .3;
-  left: 0;
-  top: 0; }
-
-.noty_modal.noty_modal_open {
-  opacity: 0;
-  -webkit-animation: noty_modal_in .3s ease-out;
-          animation: noty_modal_in .3s ease-out; }
-
-.noty_modal.noty_modal_close {
-  -webkit-animation: noty_modal_out .3s ease-out;
-          animation: noty_modal_out .3s ease-out;
-  -webkit-animation-fill-mode: forwards;
-          animation-fill-mode: forwards; }
-
-@-webkit-keyframes noty_modal_in {
-  100% {
-    opacity: .3; } }
-
-@keyframes noty_modal_in {
-  100% {
-    opacity: .3; } }
-
-@-webkit-keyframes noty_modal_out {
-  100% {
-    opacity: 0; } }
-
-@keyframes noty_modal_out {
-  100% {
-    opacity: 0; } }
-
-@keyframes noty_modal_out {
-  100% {
-    opacity: 0; } }
-
-@-webkit-keyframes noty_anim_in {
-  100% {
-    -webkit-transform: translate(0);
-            transform: translate(0);
-    opacity: 1; } }
-
-@keyframes noty_anim_in {
-  100% {
-    -webkit-transform: translate(0);
-            transform: translate(0);
-    opacity: 1; } }
-
-@-webkit-keyframes noty_anim_out {
-  100% {
-    -webkit-transform: translate(50%);
-            transform: translate(50%);
-    opacity: 0; } }
-
-@keyframes noty_anim_out {
-  100% {
-    -webkit-transform: translate(50%);
-            transform: translate(50%);
-    opacity: 0; } }
-
-@-webkit-keyframes noty_anim_height {
-  100% {
-    height: 0; } }
-
-@keyframes noty_anim_height {
-  100% {
-    height: 0; } }
-
-.noty_theme__relax.noty_bar {
-  margin: 4px 0;
-  overflow: hidden;
-  border-radius: 2px;
-  position: relative; }
-  .noty_theme__relax.noty_bar .noty_body {
-    padding: 10px; }
-  .noty_theme__relax.noty_bar .noty_buttons {
-    border-top: 1px solid #e7e7e7;
-    padding: 5px 10px; }
-
-.noty_theme__relax.noty_type__alert,
-.noty_theme__relax.noty_type__notification {
-  background-color: #fff;
-  border: 1px solid #dedede;
-  color: #444; }
-
-.noty_theme__relax.noty_type__warning {
-  background-color: #FFEAA8;
-  border: 1px solid #FFC237;
-  color: #826200; }
-  .noty_theme__relax.noty_type__warning .noty_buttons {
-    border-color: #dfaa30; }
-
-.noty_theme__relax.noty_type__error {
-  background-color: #FF8181;
-  border: 1px solid #e25353;
-  color: #FFF; }
-  .noty_theme__relax.noty_type__error .noty_buttons {
-    border-color: darkred; }
-
-.noty_theme__relax.noty_type__info,
-.noty_theme__relax.noty_type__information {
-  background-color: #78C5E7;
-  border: 1px solid #3badd6;
-  color: #FFF; }
-  .noty_theme__relax.noty_type__info .noty_buttons,
-  .noty_theme__relax.noty_type__information .noty_buttons {
-    border-color: #0B90C4; }
-
-.noty_theme__relax.noty_type__success {
-  background-color: #BCF5BC;
-  border: 1px solid #7cdd77;
-  color: darkgreen; }
-  .noty_theme__relax.noty_type__success .noty_buttons {
-    border-color: #50C24E; }
-
-.noty_theme__metroui.noty_bar {
-  margin: 4px 0;
-  overflow: hidden;
-  position: relative;
-  box-shadow: rgba(0, 0, 0, 0.298039) 0 0 5px 0; }
-  .noty_theme__metroui.noty_bar .noty_progressbar {
-    position: absolute;
-    left: 0;
-    bottom: 0;
-    height: 3px;
-    width: 100%;
-    background-color: #000;
-    opacity: 0.2;
-    filter: alpha(opacity=20); }
-  .noty_theme__metroui.noty_bar .noty_body {
-    padding: 1.25em;
-    font-size: 14px; }
-  .noty_theme__metroui.noty_bar .noty_buttons {
-    padding: 0 10px .5em 10px; }
-
-.noty_theme__metroui.noty_type__alert,
-.noty_theme__metroui.noty_type__notification {
-  background-color: #fff;
-  color: #1d1d1d; }
-
-.noty_theme__metroui.noty_type__warning {
-  background-color: #FA6800;
-  color: #fff; }
-
-.noty_theme__metroui.noty_type__error {
-  background-color: #CE352C;
-  color: #FFF; }
-
-.noty_theme__metroui.noty_type__info,
-.noty_theme__metroui.noty_type__information {
-  background-color: #1BA1E2;
-  color: #FFF; }
-
-.noty_theme__metroui.noty_type__success {
-  background-color: #60A917;
-  color: #fff; }
-
-.noty_theme__mint.noty_bar {
-  margin: 4px 0;
-  overflow: hidden;
-  border-radius: 2px;
-  position: relative; }
-  .noty_theme__mint.noty_bar .noty_body {
-    padding: 10px;
-    font-size: 14px; }
-  .noty_theme__mint.noty_bar .noty_buttons {
-    padding: 10px; }
-
-.noty_theme__mint.noty_type__alert,
-.noty_theme__mint.noty_type__notification {
-  background-color: #fff;
-  border-bottom: 1px solid #D1D1D1;
-  color: #2F2F2F; }
-
-.noty_theme__mint.noty_type__warning {
-  background-color: #FFAE42;
-  border-bottom: 1px solid #E89F3C;
-  color: #fff; }
-
-.noty_theme__mint.noty_type__error {
-  background-color: #DE636F;
-  border-bottom: 1px solid #CA5A65;
-  color: #fff; }
-
-.noty_theme__mint.noty_type__info,
-.noty_theme__mint.noty_type__information {
-  background-color: #7F7EFF;
-  border-bottom: 1px solid #7473E8;
-  color: #fff; }
-
-.noty_theme__mint.noty_type__success {
-  background-color: #AFC765;
-  border-bottom: 1px solid #A0B55C;
-  color: #fff; }
-
-.noty_theme__sunset.noty_bar {
-  margin: 4px 0;
-  overflow: hidden;
-  border-radius: 2px;
-  position: relative; }
-  .noty_theme__sunset.noty_bar .noty_body {
-    padding: 10px;
-    font-size: 14px;
-    text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1); }
-  .noty_theme__sunset.noty_bar .noty_buttons {
-    padding: 10px; }
-
-.noty_theme__sunset.noty_type__alert,
-.noty_theme__sunset.noty_type__notification {
-  background-color: #073B4C;
-  color: #fff; }
-  .noty_theme__sunset.noty_type__alert .noty_progressbar,
-  .noty_theme__sunset.noty_type__notification .noty_progressbar {
-    background-color: #fff; }
-
-.noty_theme__sunset.noty_type__warning {
-  background-color: #FFD166;
-  color: #fff; }
-
-.noty_theme__sunset.noty_type__error {
-  background-color: #EF476F;
-  color: #fff; }
-  .noty_theme__sunset.noty_type__error .noty_progressbar {
-    opacity: .4; }
-
-.noty_theme__sunset.noty_type__info,
-.noty_theme__sunset.noty_type__information {
-  background-color: #118AB2;
-  color: #fff; }
-  .noty_theme__sunset.noty_type__info .noty_progressbar,
-  .noty_theme__sunset.noty_type__information .noty_progressbar {
-    opacity: .6; }
-
-.noty_theme__sunset.noty_type__success {
-  background-color: #06D6A0;
-  color: #fff; }
-
-.noty_theme__bootstrap-v3.noty_bar {
-  margin: 4px 0;
-  overflow: hidden;
-  position: relative;
-  border: 1px solid transparent;
-  border-radius: 4px; }
-  .noty_theme__bootstrap-v3.noty_bar .noty_body {
-    padding: 15px; }
-  .noty_theme__bootstrap-v3.noty_bar .noty_buttons {
-    padding: 10px; }
-  .noty_theme__bootstrap-v3.noty_bar .noty_close_button {
-    font-size: 21px;
-    font-weight: 700;
-    line-height: 1;
-    color: #000;
-    text-shadow: 0 1px 0 #fff;
-    filter: alpha(opacity=20);
-    opacity: .2;
-    background: transparent; }
-  .noty_theme__bootstrap-v3.noty_bar .noty_close_button:hover {
-    background: transparent;
-    text-decoration: none;
-    cursor: pointer;
-    filter: alpha(opacity=50);
-    opacity: .5; }
-
-.noty_theme__bootstrap-v3.noty_type__alert,
-.noty_theme__bootstrap-v3.noty_type__notification {
-  background-color: #fff;
-  color: inherit; }
-
-.noty_theme__bootstrap-v3.noty_type__warning {
-  background-color: #fcf8e3;
-  color: #8a6d3b;
-  border-color: #faebcc; }
-
-.noty_theme__bootstrap-v3.noty_type__error {
-  background-color: #f2dede;
-  color: #a94442;
-  border-color: #ebccd1; }
-
-.noty_theme__bootstrap-v3.noty_type__info,
-.noty_theme__bootstrap-v3.noty_type__information {
-  background-color: #d9edf7;
-  color: #31708f;
-  border-color: #bce8f1; }
-
-.noty_theme__bootstrap-v3.noty_type__success {
-  background-color: #dff0d8;
-  color: #3c763d;
-  border-color: #d6e9c6; }
-
-.noty_theme__bootstrap-v4.noty_bar {
-  margin: 4px 0;
-  overflow: hidden;
-  position: relative;
-  border: 1px solid transparent;
-  border-radius: .25rem; }
-  .noty_theme__bootstrap-v4.noty_bar .noty_body {
-    padding: .75rem 1.25rem; }
-  .noty_theme__bootstrap-v4.noty_bar .noty_buttons {
-    padding: 10px; }
-  .noty_theme__bootstrap-v4.noty_bar .noty_close_button {
-    font-size: 1.5rem;
-    font-weight: 700;
-    line-height: 1;
-    color: #000;
-    text-shadow: 0 1px 0 #fff;
-    filter: alpha(opacity=20);
-    opacity: .5;
-    background: transparent; }
-  .noty_theme__bootstrap-v4.noty_bar .noty_close_button:hover {
-    background: transparent;
-    text-decoration: none;
-    cursor: pointer;
-    filter: alpha(opacity=50);
-    opacity: .75; }
-
-.noty_theme__bootstrap-v4.noty_type__alert,
-.noty_theme__bootstrap-v4.noty_type__notification {
-  background-color: #fff;
-  color: inherit; }
-
-.noty_theme__bootstrap-v4.noty_type__warning {
-  background-color: #fcf8e3;
-  color: #8a6d3b;
-  border-color: #faebcc; }
-
-.noty_theme__bootstrap-v4.noty_type__error {
-  background-color: #f2dede;
-  color: #a94442;
-  border-color: #ebccd1; }
-
-.noty_theme__bootstrap-v4.noty_type__info,
-.noty_theme__bootstrap-v4.noty_type__information {
-  background-color: #d9edf7;
-  color: #31708f;
-  border-color: #bce8f1; }
-
-.noty_theme__bootstrap-v4.noty_type__success {
-  background-color: #dff0d8;
-  color: #3c763d;
-  border-color: #d6e9c6; }
-
-.noty_theme__semanticui.noty_bar {
-  margin: 4px 0;
-  overflow: hidden;
-  position: relative;
-  border: 1px solid transparent;
-  font-size: 1em;
-  border-radius: .28571429rem;
-  box-shadow: 0 0 0 1px rgba(34, 36, 38, 0.22) inset, 0 0 0 0 transparent; }
-  .noty_theme__semanticui.noty_bar .noty_body {
-    padding: 1em 1.5em;
-    line-height: 1.4285em; }
-  .noty_theme__semanticui.noty_bar .noty_buttons {
-    padding: 10px; }
-
-.noty_theme__semanticui.noty_type__alert,
-.noty_theme__semanticui.noty_type__notification {
-  background-color: #f8f8f9;
-  color: rgba(0, 0, 0, 0.87); }
-
-.noty_theme__semanticui.noty_type__warning {
-  background-color: #fffaf3;
-  color: #573a08;
-  box-shadow: 0 0 0 1px #c9ba9b inset, 0 0 0 0 transparent; }
-
-.noty_theme__semanticui.noty_type__error {
-  background-color: #fff6f6;
-  color: #9f3a38;
-  box-shadow: 0 0 0 1px #e0b4b4 inset, 0 0 0 0 transparent; }
-
-.noty_theme__semanticui.noty_type__info,
-.noty_theme__semanticui.noty_type__information {
-  background-color: #f8ffff;
-  color: #276f86;
-  box-shadow: 0 0 0 1px #a9d5de inset, 0 0 0 0 transparent; }
-
-.noty_theme__semanticui.noty_type__success {
-  background-color: #fcfff5;
-  color: #2c662d;
-  box-shadow: 0 0 0 1px #a3c293 inset, 0 0 0 0 transparent; }
-
-.noty_theme__nest.noty_bar {
-  margin: 0 0 15px 0;
-  overflow: hidden;
-  border-radius: 2px;
-  position: relative;
-  box-shadow: rgba(0, 0, 0, 0.098039) 5px 4px 10px 0; }
-  .noty_theme__nest.noty_bar .noty_body {
-    padding: 10px;
-    font-size: 14px;
-    text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.1); }
-  .noty_theme__nest.noty_bar .noty_buttons {
-    padding: 10px; }
-
-.noty_layout .noty_theme__nest.noty_bar {
-  z-index: 5; }
-
-.noty_layout .noty_theme__nest.noty_bar:nth-child(2) {
-  position: absolute;
-  top: 0;
-  margin-top: 4px;
-  margin-right: -4px;
-  margin-left: 4px;
-  z-index: 4;
-  width: 100%; }
-
-.noty_layout .noty_theme__nest.noty_bar:nth-child(3) {
-  position: absolute;
-  top: 0;
-  margin-top: 8px;
-  margin-right: -8px;
-  margin-left: 8px;
-  z-index: 3;
-  width: 100%; }
-
-.noty_layout .noty_theme__nest.noty_bar:nth-child(4) {
-  position: absolute;
-  top: 0;
-  margin-top: 12px;
-  margin-right: -12px;
-  margin-left: 12px;
-  z-index: 2;
-  width: 100%; }
-
-.noty_layout .noty_theme__nest.noty_bar:nth-child(5) {
-  position: absolute;
-  top: 0;
-  margin-top: 16px;
-  margin-right: -16px;
-  margin-left: 16px;
-  z-index: 1;
-  width: 100%; }
-
-.noty_layout .noty_theme__nest.noty_bar:nth-child(n+6) {
-  position: absolute;
-  top: 0;
-  margin-top: 20px;
-  margin-right: -20px;
-  margin-left: 20px;
-  z-index: -1;
-  width: 100%; }
-
-#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(2),
-#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(2) {
-  margin-top: 4px;
-  margin-left: -4px;
-  margin-right: 4px; }
-
-#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(3),
-#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(3) {
-  margin-top: 8px;
-  margin-left: -8px;
-  margin-right: 8px; }
-
-#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(4),
-#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(4) {
-  margin-top: 12px;
-  margin-left: -12px;
-  margin-right: 12px; }
-
-#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(5),
-#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(5) {
-  margin-top: 16px;
-  margin-left: -16px;
-  margin-right: 16px; }
-
-#noty_layout__bottomLeft .noty_theme__nest.noty_bar:nth-child(n+6),
-#noty_layout__topLeft .noty_theme__nest.noty_bar:nth-child(n+6) {
-  margin-top: 20px;
-  margin-left: -20px;
-  margin-right: 20px; }
-
-.noty_theme__nest.noty_type__alert,
-.noty_theme__nest.noty_type__notification {
-  background-color: #073B4C;
-  color: #fff; }
-  .noty_theme__nest.noty_type__alert .noty_progressbar,
-  .noty_theme__nest.noty_type__notification .noty_progressbar {
-    background-color: #fff; }
-
-.noty_theme__nest.noty_type__warning {
-  background-color: #FFD166;
-  color: #fff; }
-
-.noty_theme__nest.noty_type__error {
-  background-color: #EF476F;
-  color: #fff; }
-  .noty_theme__nest.noty_type__error .noty_progressbar {
-    opacity: .4; }
-
-.noty_theme__nest.noty_type__info,
-.noty_theme__nest.noty_type__information {
-  background-color: #118AB2;
-  color: #fff; }
-  .noty_theme__nest.noty_type__info .noty_progressbar,
-  .noty_theme__nest.noty_type__information .noty_progressbar {
-    opacity: .6; }
-
-.noty_theme__nest.noty_type__success {
-  background-color: #06D6A0;
-  color: #fff; }
-
-/*# sourceMappingURL=noty.css.map*/

+ 29 - 16
data/web/edit.php

@@ -26,6 +26,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<h4><?=$lang['edit']['alias'];?></h4>
 					<br />
 					<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+          <input type="hidden" value="0" name="active">
 					<input type="hidden" name="address" value="<?=htmlspecialchars($alias);?>">
 						<div class="form-group">
 							<label class="control-label col-sm-2" for="goto"><?=$lang['edit']['target_address'];?></label>
@@ -36,7 +37,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 						<div class="form-group">
 							<div class="col-sm-offset-2 col-sm-10">
 								<div class="checkbox">
-								<label><input type="checkbox" name="active" <?php if (isset($result['active_int']) && $result['active_int']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
+								<label><input type="checkbox" value="1" name="active" <?php if (isset($result['active_int']) && $result['active_int']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
 								</div>
 							</div>
 						</div>
@@ -66,6 +67,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 				<h4><?=$lang['edit']['domain_admin'];?></h4>
 				<br />
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+        <input type="hidden" value="0" name="active">
 				<input type="hidden" name="username_now" value="<?=htmlspecialchars($domain_admin);?>">
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="username"><?=$lang['edit']['username'];?></label>
@@ -107,14 +109,14 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" <?php if (isset($result['active_int']) && $result['active_int']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
+							<label><input type="checkbox" value="1" name="active" <?php if (isset($result['active_int']) && $result['active_int']=="1") { echo "checked"; }; ?>> <?=$lang['edit']['active'];?></label>
 							</div>
 						</div>
 					</div>
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="disable_tfa"> <?=$lang['tfa']['disable_tfa'];?></label>
+							<label><input type="checkbox" value="1" name="disable_tfa"> <?=$lang['tfa']['disable_tfa'];?></label>
 							</div>
 						</div>
 					</div>
@@ -141,6 +143,9 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 			?>
 				<h4><?=$lang['edit']['domain'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+        <input type="hidden" value="0" name="active">
+        <input type="hidden" value="0" name="backupmx">
+        <input type="hidden" value="0" name="relay_all_recipients">
 				<input type="hidden" name="domain" value="<?=htmlspecialchars($domain);?>">
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="description"><?=$lang['edit']['description'];?></label>
@@ -179,9 +184,9 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 						<label class="control-label col-sm-2"><?=$lang['edit']['backup_mx_options'];?></label>
 						<div class="col-sm-10">
 							<div class="checkbox">
-								<label><input type="checkbox" name="backupmx" <?=(isset($result['backupmx_int']) && $result['backupmx_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['relay_domain'];?></label>
+								<label><input type="checkbox" value="1" name="backupmx" <?=(isset($result['backupmx_int']) && $result['backupmx_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['relay_domain'];?></label>
 								<br />
-								<label><input type="checkbox" name="relay_all_recipients" <?=(isset($result['relay_all_recipients_int']) && $result['relay_all_recipients_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['relay_all'];?></label>
+								<label><input type="checkbox" value="1" name="relay_all_recipients" <?=(isset($result['relay_all_recipients_int']) && $result['relay_all_recipients_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['relay_all'];?></label>
 								<p><?=$lang['edit']['relay_all_info'];?></p>
 							</div>
 						</div>
@@ -192,7 +197,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-								<label><input type="checkbox" name="active" <?=(isset($result['active_int']) && $result['active_int']=="1") ? "checked" : null;?> <?=($_SESSION['mailcow_cc_role'] == "admin") ? null : "disabled";?>> <?=$lang['edit']['active'];?></label>
+								<label><input type="checkbox" value="1" name="active" <?=(isset($result['active_int']) && $result['active_int']=="1") ? "checked" : null;?> <?=($_SESSION['mailcow_cc_role'] == "admin") ? null : "disabled";?>> <?=$lang['edit']['active'];?></label>
 							</div>
 						</div>
 					</div>
@@ -350,17 +355,18 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 			?>
 				<h4><?=$lang['edit']['edit_alias_domain'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
-					<input type="hidden" name="alias_domain_now" value="<?=htmlspecialchars($alias_domain);?>">
+          <input type="hidden" value="0" name="active">
+          <input type="hidden" value="<?=$result['alias_domain'];?>" name="alias_domain">
 					<div class="form-group">
-						<label class="control-label col-sm-2" for="alias_domain"><?=$lang['edit']['alias_domain'];?></label>
+						<label class="control-label col-sm-2" for="target_domain"><?=$lang['edit']['target_domain'];?></label>
 						<div class="col-sm-10">
-							<input type="text" class="form-control" name="alias_domain" id="alias_domain" value="<?=htmlspecialchars($result['alias_domain']);?>">
+							<input type="text" class="form-control" name="target_domain" id="target_domain" value="<?=htmlspecialchars($result['target_domain']);?>">
 						</div>
 					</div>
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-								<label><input type="checkbox" name="active" <?=(isset($result['active_int']) && $result['active_int']=="1") ?  "checked" : null ?>> <?=$lang['edit']['active'];?></label>
+								<label><input type="checkbox" value="1" name="active" <?=(isset($result['active_int']) && $result['active_int']=="1") ?  "checked" : null ?>> <?=$lang['edit']['active'];?></label>
 							</div>
 						</div>
 					</div>
@@ -398,6 +404,8 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
       ?>
       <h4><?=$lang['edit']['mailbox'];?></h4>
       <form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+      <input type="hidden" value="0" name="sender_acl">
+      <input type="hidden" value="0" name="active">
       <input type="hidden" name="username" value="<?=htmlspecialchars($result['username']);?>">
         <div class="form-group">
           <label class="control-label col-sm-2" for="name"><?=$lang['edit']['full_name'];?>:</label>
@@ -481,7 +489,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
         <div class="form-group">
           <div class="col-sm-offset-2 col-sm-10">
             <div class="checkbox">
-            <label><input type="checkbox" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
+            <label><input type="checkbox" value="1" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
             </div>
           </div>
         </div>
@@ -501,6 +509,8 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
         ?>
 				<h4><?=$lang['edit']['resource'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+          <input type="hidden" value="0" name="active">
+          <input type="hidden" value="0" name="multiple_bookings">
           <input type="hidden" name="name" value="<?=htmlspecialchars($result['name']);?>">
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="description"><?=$lang['add']['description'];?></label>
@@ -521,14 +531,14 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
+							<label><input type="checkbox" value="1" name="active" <?=($result['active_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['active'];?></label>
 							</div>
 						</div>
 					</div>
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="multiple_bookings" <?=($result['multiple_bookings_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['multiple_bookings'];?></label>
+							<label><input type="checkbox" value="1" name="multiple_bookings" <?=($result['multiple_bookings_int']=="1") ? "checked" : null;?>> <?=$lang['edit']['multiple_bookings'];?></label>
 							</div>
 						</div>
 					</div>
@@ -561,6 +571,9 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
 			?>
 				<h4><?=$lang['edit']['syncjob'];?></h4>
 				<form class="form-horizontal" role="form" method="post" action="<?=($FORM_ACTION == "previous") ? $_SESSION['return_to'] : null;?>">
+        <input type="hidden" value="0" name="delete2duplicates">
+        <input type="hidden" value="0" name="delete1">
+        <input type="hidden" value="0" name="active">
 				<input type="hidden" name="id" value="<?=htmlspecialchars($result['id']);?>">
 					<div class="form-group">
 						<label class="control-label col-sm-2" for="host1"><?=$lang['edit']['hostname'];?></label>
@@ -623,21 +636,21 @@ elseif (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] ==
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="delete2duplicates" <?=($result['delete2duplicates']=="1") ? "checked" : "";?>> <?=$lang['edit']['delete2duplicates'];?></label>
+							<label><input type="checkbox" value="1" name="delete2duplicates" <?=($result['delete2duplicates']=="1") ? "checked" : "";?>> <?=$lang['edit']['delete2duplicates'];?></label>
 							</div>
 						</div>
 					</div>
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="delete1" <?=($result['delete1']=="1") ? "checked" : "";?>> <?=$lang['edit']['delete1'];?></label>
+							<label><input type="checkbox" value="1" name="delete1" <?=($result['delete1']=="1") ? "checked" : "";?>> <?=$lang['edit']['delete1'];?></label>
 							</div>
 						</div>
 					</div>
 					<div class="form-group">
 						<div class="col-sm-offset-2 col-sm-10">
 							<div class="checkbox">
-							<label><input type="checkbox" name="active" <?=($result['active']=="1") ? "checked" : "";?>> <?=$lang['edit']['active'];?></label>
+							<label><input type="checkbox" value="1" name="active" <?=($result['active']=="1") ? "checked" : "";?>> <?=$lang['edit']['active'];?></label>
 							</div>
 						</div>
 					</div>

+ 4 - 1
data/web/inc/footer.inc.php

@@ -226,12 +226,15 @@ $(document).ready(function() {
 			}
 		});
 	});
+
+  if ($('#mailcow-alert').hasClass('alert-success')) {
+    $('#mailcow-alert').delay(5000).animate({right: '-50%'}, 1000);
+  };
 });
 </script>
 
 <div class="container">
   <div id="mailcow-alert" class="alert" role="alert">
-    <a href="#" class="close" data-dismiss="alert"> &times;</a>
     <span id="mailcow-alert-text"></span>
   </div>
 </div>

File diff suppressed because it is too large
+ 515 - 392
data/web/inc/functions.inc.php


+ 3 - 2
data/web/inc/vars.inc.php

@@ -1,6 +1,7 @@
 <?php
-error_reporting(E_ERROR);
-//error_reporting(E_ALL);
+//error_reporting(E_ERROR);
+error_reporting(E_ALL);
+header('X-Powered-By: mailcow');
 
 /*
 PLEASE USE THE FILE "vars.local.inc.php" TO OVERWRITE SETTINGS AND MAKE THEM PERSISTENT!

+ 167 - 198
data/web/js/admin.js

@@ -1,17 +1,16 @@
 $(document).ready(function() {
-  
-  // Collect values of input fields with name multi_select with same data-form-id to js array multi_data[data-form-id-of-checkbox]
+  // Collect values of input fields with name multi_select with same data-id to js array multi_data[data-id]
   var multi_data = [];
   $(document).on('change', 'input[name=multi_select]:checkbox', function() {
-    if ($(this).is(':checked') && $(this).attr('data-form-id')) {
-      var id = $(this).data('form-id');
+    if ($(this).is(':checked') && $(this).data('id')) {
+      var id = $(this).data('id');
       if (typeof multi_data[id] == "undefined") {
         multi_data[id] = [];
       }
       multi_data[id].push($(this).val());
     }
     else {
-      var id = $(this).data('form-id');
+      var id = $(this).data('id');
       multi_data[id].splice($.inArray($(this).val(), multi_data[id]),1);
     }
   });
@@ -24,104 +23,21 @@ $(document).ready(function() {
       checkbox.trigger('click');
     }
   });
-  // Select or deselect all checkboxes with same data-form-id
+  // Select or deselect all checkboxes with same data-id
   $(document).on('click', '#toggle_multi_select_all', function(e) {
     e.preventDefault();
-    var all_checkboxes = $("input[data-form-id=" + $(this).attr("data-form-id") + "]");
+    id = $(this).data("id");
+    multi_data[id] = [];
+    var all_checkboxes = $("input[data-id=" + id + "]:enabled");
     all_checkboxes.prop("checked", !all_checkboxes.prop("checked")).change();
   });
-
-  // Draw domain admin table
-  $.ajax({
-    dataType: 'json',
-    url: '/api/v1/get/domain-admin/all',
-    jsonp: false,
-    error: function () {
-      console.log('Cannot draw domain admin table');
-    },
-    success: function (data) {
-      $.each(data, function (i, item) {
-        item.action = '<div class="btn-group">' +
-          '<a href="/edit.php?domainadmin=' + encodeURI(item.username) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
-          '<a href="/delete.php?domainadmin=' + encodeURI(item.username) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
-					'</div>';
-      });
-      $('#domainadminstable').footable({
-        "columns": [
-          {"sorted": true,"name":"username","title":lang.username,"style":{"width":"250px"}},
-          {"name":"selected_domains","title":lang.admin_domains,"breakpoints":"xs sm"},
-          {"name":"tfa_active","title":"TFA", "filterable": false,"style":{"maxWidth":"80px","width":"80px"}},
-          {"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
-          {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
-        ],
-        "rows": data,
-        "empty": lang.empty,
-        "paging": {
-          "enabled": true,
-          "limit": 5,
-          "size": pagination_size
-        },
-        "filtering": {
-          "enabled": true,
-          "position": "left",
-          "placeholder": lang.filter_table
-        },
-        "sorting": {
-          "enabled": true
-        }
-      });
-    }
-  });
-  
-  // Draw fwd hosts table
-  $.ajax({
-    dataType: 'json',
-    url: '/api/v1/get/fwdhost/all',
-    jsonp: false,
-    error: function () {
-      console.log('Cannot draw forwarding hosts table');
-    },
-    success: function (data) {
-      $.each(data, function (i, item) {
-        item.action = '<div class="btn-group">' +
-          '<a href="/delete.php?forwardinghost=' + encodeURI(item.host) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
-					'</div>';
-        if (item.keep_spam == "yes") {
-          item.keep_spam = lang.no;
-        }
-        else {
-          item.keep_spam = lang.yes;
-        }
-        item.chkbox = '<input type="checkbox" data-form-id="fwdhosts" name="multi_select" value="' + item.host + '" />';
-      });
-      $('#forwardinghoststable').footable({
-        "columns": [
-          {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
-          {"name":"host","type":"text","title":lang.host,"style":{"width":"250px"}},
-          {"name":"source","title":lang.source,"breakpoints":"xs sm"},
-          {"name":"keep_spam","title":lang.spamfilter, "type": "text","style":{"maxWidth":"80px","width":"80px"}},
-          {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
-        ],
-        "rows": data,
-        "empty": lang.empty,
-        "paging": {
-          "enabled": true,
-          "limit": 5,
-          "size": pagination_size
-        },
-        "sorting": {
-          "enabled": true
-        }
-      });
-    }
-  });
-  
-  $(document).on('click', '#delete_fwdhosts', function(e) {
+  // General API edit function
+  $(document).on('click', '#delete_selected', function(e) {
     e.preventDefault();
-    var id = $(this).closest("form").attr('data-id');
-    if (typeof multi_data[id] == "undefined") return;
+    var id = $(this).data('id');
+    if (typeof multi_data[id] == "undefined" || multi_data[id] == "") return;
     data_array = multi_data[id];
-    if (Object.keys(data_array).length !== 0) {
+    api_url = $(this).data('api-url');
       $(document).on('show.bs.modal','#ConfirmDeleteModal', function () {
         $("#ItemsToDelete").empty();
         for (var i in data_array) {
@@ -136,64 +52,46 @@ $(document).ready(function() {
         $.ajax({
           type: "POST",
           dataType: "json",
-          data: { "forwardinghost": JSON.stringify(data_array) },
-          url: '/api/v1/delete/fwdhost',
+          data: { "items": JSON.stringify(data_array) },
+          url: '/api/v1/' + api_url,
           jsonp: false,
           complete: function (data) {
-            window.location.href = window.location.href;
+            location.assign(window.location);
           }
         });
       })
       .one('click', '#isCanceled', function(e) {
         $('#ConfirmDeleteModal').modal('hide');
       });;
-    }
   });
 
-  $(document).on('click', '#delete_dkim_key', function(e) {
+});
+jQuery(function($){
+  function unix_time_format(tm) {
+    var date = new Date(tm ? tm * 1000 : 0);
+    return date.toLocaleString();
+  }
+  $("#refresh_postfix_log").on('click', function(e) {
     e.preventDefault();
-    var dkim_domain = $(this).data('dkim-domain');
-    var dkim_selector = $(this).data('dkim-selector');
-      $(document).on('show.bs.modal','#ConfirmDeleteModal', function () {
-        $("#ItemsToDelete").empty();
-        $("#ItemsToDelete").append("<li>" + dkim_domain + ", " + dkim_selector + "</li>");
-      })
-      $('#ConfirmDeleteModal').modal({
-        backdrop: 'static',
-        keyboard: false
-      })
-      .one('click', '#IsConfirmed', function(e) {
-        $.ajax({
-          type: "POST",
-          dataType: "json",
-          data: { "domains": JSON.stringify(dkim_domain) },
-          url: '/api/v1/delete/dkim',
-          jsonp: false,
-          complete: function (data) {
-            mailcow_alert_box("warn", "asd");
-          }
-        });
-      })
-      .one('click', '#isCanceled', function(e) {
-        $('#ConfirmDeleteModal').modal('hide');
-      });;
+    draw_postfix_logs();
   });
-
   $("#refresh_dovecot_log").on('click', function(e) {
-      function unix_time_format(tm) {
-        var date = new Date(tm ? tm * 1000 : 0);
-        return date.toLocaleString();
-      }
-      e.preventDefault();
-      if (typeof ft_dovecot_logs != 'undefined') {
-        ft_dovecot_logs.destroy();
-      }
-      $.ajax({
+    e.preventDefault();
+    draw_dovecot_logs();
+  });
+  function draw_postfix_logs() {
+    ft_postfix_logs = FooTable.init('#postfix_log', {
+      "columns": [
+        {"name":"time","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.time,"style":{"width":"170px"}},
+        {"name":"priority","title":lang.priority,"style":{"width":"80px"}},
+        {"name":"message","title":lang.message},
+      ],
+      "rows": $.ajax({
         dataType: 'json',
-        url: '/api/v1/get/logs/dovecot/1000',
+        url: '/api/v1/get/logs/postfix/1000',
         jsonp: false,
         error: function () {
-          console.log('Cannot draw dovecot log table');
+          console.log('Cannot draw postfix log table');
         },
         success: function (data) {
           $.each(data, function (i, item) {
@@ -210,46 +108,37 @@ $(document).ready(function() {
               item.priority = '<span class="label label-info">' + item.priority + '</span>';
             }
           });
-          ft_dovecot_logs = FooTable.init("#dovecot_log", {
-            "columns": [
-              {"name":"time","formatter":function unix_time_format(tm) {var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.time,"style":{"width":"170px"}},
-              {"name":"priority","title":lang.priority,"style":{"width":"80px"}},
-              {"name":"message","title":lang.message},
-            ],
-            "rows": data,
-            "empty": lang.empty,
-            "paging": {
-              "enabled": true,
-              "limit": 5,
-              "size": pagination_size
-            },
-            "filtering": {
-              "enabled": true,
-              "position": "left",
-              "placeholder": lang.filter_table
-            },
-            "sorting": {
-              "enabled": true
-            }
-          });
         }
-      });
-  });
-  $("#refresh_postfix_log").on('click', function(e) {
-      function unix_time_format(tm) {
-        var date = new Date(tm ? tm * 1000 : 0);
-        return date.toLocaleString();
+      }),
+      "empty": lang.empty,
+      "paging": {
+        "enabled": true,
+        "limit": 5,
+        "size": pagination_size
+      },
+      "filtering": {
+        "enabled": true,
+        "position": "left",
+        "placeholder": lang.filter_table
+      },
+      "sorting": {
+        "enabled": true
       }
-      e.preventDefault();
-      if (typeof ft_postfix_logs != 'undefined') {
-        ft_postfix_logs.destroy();
-      }
-      $.ajax({
+    });
+  }
+  function draw_dovecot_logs() {
+    ft_postfix_logs = FooTable.init('#dovecot_log', {
+      "columns": [
+        {"name":"time","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.time,"style":{"width":"170px"}},
+        {"name":"priority","title":lang.priority,"style":{"width":"80px"}},
+        {"name":"message","title":lang.message},
+      ],
+      "rows": $.ajax({
         dataType: 'json',
-        url: '/api/v1/get/logs/postfix/1000',
+        url: '/api/v1/get/logs/dovecot/1000',
         jsonp: false,
         error: function () {
-          console.log('Cannot draw postfix log table');
+          console.log('Cannot draw dovecot log table');
         },
         success: function (data) {
           $.each(data, function (i, item) {
@@ -266,31 +155,111 @@ $(document).ready(function() {
               item.priority = '<span class="label label-info">' + item.priority + '</span>';
             }
           });
-          ft_postfix_logs = FooTable.init("#postfix_log", {
-            "columns": [
-              {"name":"time","formatter":function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); return date.toLocaleString();},"title":lang.time,"style":{"width":"170px"}},
-              {"name":"priority","title":lang.priority,"style":{"width":"80px"}},
-              {"name":"message","title":lang.message},
-            ],
-            "rows": data,
-            "empty": lang.empty,
-            "paging": {
-              "enabled": true,
-              "limit": 5,
-              "size": pagination_size
-            },
-            "filtering": {
-              "enabled": true,
-              "position": "left",
-              "placeholder": lang.filter_table
-            },
-            "sorting": {
-              "enabled": true
+        }
+      }),
+      "empty": lang.empty,
+      "paging": {
+        "enabled": true,
+        "limit": 5,
+        "size": pagination_size
+      },
+      "filtering": {
+        "enabled": true,
+        "position": "left",
+        "placeholder": lang.filter_table
+      },
+      "sorting": {
+        "enabled": true
+      }
+    });
+  }
+  function draw_domain_admins() {
+    ft_domainadmins = FooTable.init('#domainadminstable', {
+      "columns": [
+        {"sorted": true,"name":"username","title":lang.username,"style":{"width":"250px"}},
+        {"name":"selected_domains","title":lang.admin_domains,"breakpoints":"xs sm"},
+        {"name":"tfa_active","title":"TFA", "filterable": false,"style":{"maxWidth":"80px","width":"80px"}},
+        {"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
+        {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
+      ],
+      "rows": $.ajax({
+        dataType: 'json',
+        url: '/api/v1/get/domain-admin/all',
+        jsonp: false,
+        error: function () {
+          console.log('Cannot draw domain admin table');
+        },
+        success: function (data) {
+          $.each(data, function (i, item) {
+            item.action = '<div class="btn-group">' +
+              '<a href="/edit.php?domainadmin=' + encodeURI(item.username) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
+              '<a href="/delete.php?domainadmin=' + encodeURI(item.username) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
+              '</div>';
+          });
+        }
+      }),
+      "empty": lang.empty,
+      "paging": {
+        "enabled": true,
+        "limit": 5,
+        "size": pagination_size
+      },
+      "filtering": {
+        "enabled": true,
+        "position": "left",
+        "placeholder": lang.filter_table
+      },
+      "sorting": {
+        "enabled": true
+      }
+    });
+  }
+
+  function draw_fwd_hosts() {
+    ft_domainadmins = FooTable.init('#forwardinghoststable', {
+      "columns": [
+        {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
+        {"name":"host","type":"text","title":lang.host,"style":{"width":"250px"}},
+        {"name":"source","title":lang.source,"breakpoints":"xs sm"},
+        {"name":"keep_spam","title":lang.spamfilter, "type": "text","style":{"maxWidth":"80px","width":"80px"}},
+        {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
+      ],
+      "rows": $.ajax({
+        dataType: 'json',
+        url: '/api/v1/get/fwdhost/all',
+        jsonp: false,
+        error: function () {
+          console.log('Cannot draw forwarding hosts table');
+        },
+        success: function (data) {
+          $.each(data, function (i, item) {
+            item.action = '<div class="btn-group">' +
+              '<a href="/delete.php?forwardinghost=' + encodeURI(item.host) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
+              '</div>';
+            if (item.keep_spam == "yes") {
+              item.keep_spam = lang.no;
             }
+            else {
+              item.keep_spam = lang.yes;
+            }
+            item.chkbox = '<input type="checkbox" data-id="fwdhosts" name="multi_select" value="' + item.host + '" />';
           });
         }
-      });
-  });
-  $("#refresh_dovecot_log").trigger('click');
-  $("#refresh_postfix_log").trigger('click');
+      }),
+      "empty": lang.empty,
+      "paging": {
+        "enabled": true,
+        "limit": 5,
+        "size": pagination_size
+      },
+      "sorting": {
+        "enabled": true
+      }
+    });
+  }
+
+  draw_postfix_logs();
+  draw_dovecot_logs();
+  draw_domain_admins();
+  draw_fwd_hosts();
 });

+ 355 - 335
data/web/js/mailbox.js

@@ -1,5 +1,98 @@
 $(document).ready(function() {
-	$('[data-toggle="tooltip"]').tooltip();
+  // Collect values of input fields with name multi_select with same data-id to js array multi_data[data-id]
+  var multi_data = [];
+  $(document).on('change', 'input[name=multi_select]:checkbox', function() {
+    if ($(this).is(':checked') && $(this).data('id')) {
+      var id = $(this).data('id');
+      if (typeof multi_data[id] == "undefined") {
+        multi_data[id] = [];
+      }
+      multi_data[id].push($(this).val());
+    }
+    else {
+      var id = $(this).data('id');
+      multi_data[id].splice($.inArray($(this).val(), multi_data[id]),1);
+    }
+  });
+  // Select checkbox by click on parent tr
+  $(document).on('click', 'tr', function(e) {
+    if (e.target.type == "checkbox") {
+      e.stopPropagation();
+    } else {
+      var checkbox = $(this).find(':checkbox');
+      checkbox.trigger('click');
+    }
+  });
+  // Select or deselect all checkboxes with same data-id
+  $(document).on('click', '#toggle_multi_select_all', function(e) {
+    e.preventDefault();
+    id = $(this).data("id");
+    multi_data[id] = [];
+    var all_checkboxes = $("input[data-id=" + id + "]:enabled");
+    all_checkboxes.prop("checked", !all_checkboxes.prop("checked")).change();
+  });
+  // General API edit actions
+  $(document).on('click', '#edit_selected', function(e) {
+    e.preventDefault();
+    var id = $(this).data('id');
+    if (typeof multi_data[id] == "undefined") return;
+    data_array = multi_data[id];
+    api_url = $(this).data('api-url');
+    api_attr = $(this).data('api-attr');
+    if (Object.keys(data_array).length !== 0) {
+      $.ajax({
+        type: "POST",
+        dataType: "json",
+        data: { "items": JSON.stringify(data_array), "attr": JSON.stringify(api_attr) },
+        url: '/api/v1/' + api_url,
+        jsonp: false,
+        complete: function (data) {
+          // var reponse = (JSON.parse(data.responseText));
+          // alert(reponse.type);
+          // alert(reponse.msg);
+          location.assign(window.location);
+        }
+      });
+    }
+  });
+  // General API delete actions
+  $(document).on('click', '#delete_selected', function(e) {
+    e.preventDefault();
+    var id = $(this).data('id');
+    if (typeof multi_data[id] == "undefined" || multi_data[id] == "") return;
+    data_array = multi_data[id];
+    api_url = $(this).data('api-url');
+      $(document).on('show.bs.modal','#ConfirmDeleteModal', function () {
+        $("#ItemsToDelete").empty();
+        for (var i in data_array) {
+          $("#ItemsToDelete").append("<li>" + data_array[i] + "</li>");
+        }
+      })
+      $('#ConfirmDeleteModal').modal({
+        backdrop: 'static',
+        keyboard: false
+      })
+      .one('click', '#IsConfirmed', function(e) {
+        $.ajax({
+          type: "POST",
+          dataType: "json",
+          data: { "items": JSON.stringify(data_array) },
+          url: '/api/v1/' + api_url,
+          jsonp: false,
+          complete: function (data) {
+            location.assign(window.location);
+          }
+        });
+      })
+      .one('click', '#isCanceled', function(e) {
+        $('#ConfirmDeleteModal').modal('hide');
+      });;
+  });
+
+});
+
+jQuery(function($){
+  // Calculation human readable file sizes
   function humanFileSize(bytes) {
     if(Math.abs(bytes) < 1024) {
         return bytes + ' B';
@@ -12,358 +105,285 @@ $(document).ready(function() {
     } while(Math.abs(bytes) >= 1024 && u < units.length - 1);
     return bytes.toFixed(1)+' '+units[u];
   }
-
-  $.ajax({
-    dataType: 'json',
-    url: '/api/v1/get/domain/all',
-    jsonp: false,
-    error: function () {
-      alert('Cannot draw domain table');
-    },
-    success: function (data) {
-      $.each(data, function (i, item) {
-        item.aliases = item.aliases_in_domain + " / " + item.max_num_aliases_for_domain;
-        item.mailboxes = item.mboxes_in_domain + " / " + item.max_num_mboxes_for_domain;
-        item.quota = item.quota_used_in_domain + "/" + item.max_quota_for_domain;
-        item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
-        if (role == "admin") {
-        item.action = '<div class="btn-group">' +
-          '<a href="/edit.php?domain=' + encodeURI(item.domain_name) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
-          '<a href="/delete.php?domain=' + encodeURI(item.domain_name) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
-					'</div>';
-        }
-        else {
-        item.action = '<div class="btn-group">' +
-          '<a href="/edit.php?domain=' + encodeURI(item.domain_name) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
-					'</div>';
-        }
-      });
-      $('#domain_table').footable({
-        "columns": [
-          {"sorted": true,"name":"domain_name","title":lang.domain,"style":{"width":"250px"}},
-          {"name":"aliases","title":lang.aliases,"breakpoints":"xs sm"},
-          {"name":"mailboxes","title":lang.mailboxes},
-          {"name":"quota","style":{"whiteSpace":"nowrap"},"title":lang.domain_quota,"formatter": function(value){
-            res = value.split("/");
-            return humanFileSize(res[0]) + " / " + humanFileSize(res[1]);
-          },
-          "sortValue": function(value){
-            res = value.split("/");
-            return res[0];
-          },
-          },
-          {"name":"max_quota_for_mbox","title":lang.mailbox_quota,"breakpoints":"xs sm"},
-          {"name":"backupmx","filterable": false,"style":{"maxWidth":"120px","width":"120px"},"title":lang.backup_mx,"breakpoints":"xs sm"},
-          {"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
-          {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
-        ],
-        "rows": data,
-        "empty": lang.empty,
-        "paging": {
-          "enabled": true,
-          "limit": 5,
-          "size": pagination_size
+  function unix_time_format(tm) {
+    var date = new Date(tm ? tm * 1000 : 0);
+    return date.toLocaleString();
+  }
+  function draw_domain_table() {
+    ft_domain_table = FooTable.init('#domain_table', {
+      "columns": [
+        {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
+        {"sorted": true,"name":"domain_name","title":lang.domain,"style":{"width":"250px"}},
+        {"name":"aliases","title":lang.aliases,"breakpoints":"xs sm"},
+        {"name":"mailboxes","title":lang.mailboxes},
+        {"name":"quota","style":{"whiteSpace":"nowrap"},"title":lang.domain_quota,"formatter": function(value){
+          res = value.split("/");
+          return humanFileSize(res[0]) + " / " + humanFileSize(res[1]);
         },
-        "filtering": {
-          "enabled": true,
-          "position": "left",
-          "placeholder": lang.filter_table
+        "sortValue": function(value){
+          res = value.split("/");
+          return res[0];
         },
-        "sorting": {
-          "enabled": true
-        }
-      });
-    }
-  });
-
-  $.ajax({
-    dataType: 'json',
-    url: '/api/v1/get/mailbox/all',
-    jsonp: false,
-    error: function () {
-      alert('Cannot draw mailbox table');
-    },
-    success: function (data) {
-      $.each(data, function (i, item) {
-        item.quota = item.quota_used + "/" + item.quota;
-        item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
-        if (role == "admin") {
-        item.action = '<div class="btn-group">' +
-          '<a href="/edit.php?mailbox=' + encodeURI(item.username) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
-          '<a href="/delete.php?mailbox=' + encodeURI(item.username) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
-          '<a href="/index.php?duallogin=' + encodeURI(item.username) + '" class="btn btn-xs btn-success"><span class="glyphicon glyphicon-user"></span> Login</a>' +
-					'</div>';
-        }
-        else {
-        item.action = '<div class="btn-group">' +
-          '<a href="/edit.php?mailbox=' + encodeURI(item.username) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
-          '<a href="/delete.php?mailbox=' + encodeURI(item.username) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
-					'</div>';
-        }
-        item.in_use = '<div class="progress">' +
-				  '<div class="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>';
-
-      });
-      $('#mailbox_table').footable({
-        "columns": [
-          {"sorted": true,"name":"username","style":{"word-break":"break-all","min-width":"120px"},"title":lang.username},
-          {"name":"name","title":lang.fname,"style":{"word-break":"break-all","min-width":"120px"},"breakpoints":"xs sm"},
-          {"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
-          {"name":"quota","style":{"whiteSpace":"nowrap"},"title":lang.domain_quota,"formatter": function(value){
-            res = value.split("/");
-            return humanFileSize(res[0]) + " / " + humanFileSize(res[1]);
-          },
-          "sortValue": function(value){
-            res = value.split("/");
-            return res[0];
-          },
-          },
-          {"name":"spam_aliases","filterable": false,"title":lang.spam_aliases,"breakpoints":"xs sm md"},
-          {"name":"in_use","filterable": false,"type":"html","title":lang.in_use},
-          {"name":"messages","filterable": false,"title":lang.msg_num,"breakpoints":"xs sm md"},
-          {"name":"active","filterable": false,"title":lang.active},
-          {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
-        ],
-        "empty": lang.empty,
-        "rows": data,
-        "paging": {
-          "enabled": true,
-          "limit": 5,
-          "size": pagination_size
         },
-        "filtering": {
-          "enabled": true,
-          "position": "left",
-          "placeholder": lang.filter_table
+        {"name":"max_quota_for_mbox","title":lang.mailbox_quota,"breakpoints":"xs sm"},
+        {"name":"backupmx","filterable": false,"style":{"maxWidth":"120px","width":"120px"},"title":lang.backup_mx,"breakpoints":"xs sm"},
+        {"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
+      ],
+      "rows": $.ajax({
+        dataType: 'json',
+        url: '/api/v1/get/domain/all',
+        jsonp: false,
+        error: function () {
+          alert('Cannot draw domain table');
         },
-        "sorting": {
-          "enabled": true
+        success: function (data) {
+          $.each(data, function (i, item) {
+            item.aliases = item.aliases_in_domain + " / " + item.max_num_aliases_for_domain;
+            item.mailboxes = item.mboxes_in_domain + " / " + item.max_num_mboxes_for_domain;
+            item.quota = item.quota_used_in_domain + "/" + item.max_quota_for_domain;
+            item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
+            item.chkbox = '<input type="checkbox" data-id="domain" name="multi_select" value="' + item.domain_name + '" />';
+            if (role == "admin") {
+              item.action = '<div class="btn-group">' +
+                '<a href="/edit.php?domain=' + encodeURI(item.domain_name) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
+                '<a href="/delete.php?domain=' + encodeURI(item.domain_name) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
+                '</div>';
+            }
+            else {
+              item.action = '<div class="btn-group">' +
+                '<a href="/edit.php?domain=' + encodeURI(item.domain_name) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
+                '</div>';
+            }
+          });
         }
-      });
-    }
-  });
-
-  $.ajax({
-    dataType: 'json',
-    url: '/api/v1/get/resource/all',
-    jsonp: false,
-    error: function () {
-      alert('Cannot draw resource table');
-    },
-    success: function (data) {
-      $.each(data, function (i, item) {
-        item.action = '<div class="btn-group">' +
-          '<a href="/edit.php?resource=' + encodeURI(item.name) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
-          '<a href="/delete.php?resource=' + encodeURI(item.name) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
-					'</div>';
-      });
-      $('#resources_table').footable({
-        "columns": [
-          {"sorted": true,"name":"description","title":lang.description,"style":{"width":"250px"}},
-          {"name":"kind","title":lang.kind},
-          {"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
-          {"name":"multiple_bookings","filterable": false,"style":{"maxWidth":"120px","width":"120px"},"title":lang.multiple_bookings,"breakpoints":"xs sm"},
-          {"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
-          {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
-        ],
-        "empty": lang.empty,
-        "rows": data,
-        "paging": {
-          "enabled": true,
-          "limit": 5,
-          "size": pagination_size
+      }),
+      "empty": lang.empty,
+      "paging": {
+        "enabled": true,
+        "limit": 5,
+        "size": pagination_size
+      },
+      "filtering": {
+        "enabled": true,
+        "position": "left",
+        "placeholder": lang.filter_table
+      },
+      "sorting": {
+        "enabled": true
+      }
+    });
+  }
+  function draw_mailbox_table() {
+    ft_mailbox_table = FooTable.init('#mailbox_table', {
+      "columns": [
+        {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
+        {"sorted": true,"name":"username","style":{"word-break":"break-all","min-width":"120px"},"title":lang.username},
+        {"name":"name","title":lang.fname,"style":{"word-break":"break-all","min-width":"120px"},"breakpoints":"xs sm"},
+        {"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
+        {"name":"quota","style":{"whiteSpace":"nowrap"},"title":lang.domain_quota,"formatter": function(value){
+          res = value.split("/");
+          return humanFileSize(res[0]) + " / " + humanFileSize(res[1]);
         },
-        "filtering": {
-          "enabled": true,
-          "position": "left",
-          "placeholder": lang.filter_table
+        "sortValue": function(value){
+          res = value.split("/");
+          return res[0];
         },
-        "sorting": {
-          "enabled": true
-        }
-      });
-    }
-  });
-
-  $.ajax({
-    dataType: 'json',
-    url: '/api/v1/get/alias-domain/all',
-    jsonp: false,
-    error: function () {
-      alert('Cannot draw alias domain table');
-    },
-    success: function (data) {
-      $.each(data, function (i, item) {
-        item.action = '<div class="btn-group">' +
-          '<a href="/edit.php?aliasdomain=' + encodeURI(item.alias_domain) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
-          '<a href="/delete.php?aliasdomain=' + encodeURI(item.alias_domain) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
-					'</div>';
-      });
-      $('#aliasdomain_table').footable({
-        "columns": [
-          {"sorted": true,"name":"alias_domain","title":lang.alias,"style":{"width":"250px"}},
-          {"name":"target_domain","title":lang.target_domain},
-          {"name":"active","filterable": false,"style":{"maxWidth":"50px","width":"70px"},"title":lang.active},
-          {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
-        ],
-        "empty": lang.empty,
-        "rows": data,
-        "paging": {
-          "enabled": true,
-          "limit": 5,
-          "size": pagination_size
         },
-        "filtering": {
-          "enabled": true,
-          "position": "left",
-          "placeholder": lang.filter_table
+        {"name":"spam_aliases","filterable": false,"title":lang.spam_aliases,"breakpoints":"xs sm md"},
+        {"name":"in_use","filterable": false,"type":"html","title":lang.in_use},
+        {"name":"messages","filterable": false,"title":lang.msg_num,"breakpoints":"xs sm md"},
+        {"name":"active","filterable": false,"title":lang.active},
+        {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","min-width":"250px"},"type":"html","title":lang.action,"breakpoints":"xs sm md"}
+      ],
+      "empty": lang.empty,
+      "rows": $.ajax({
+        dataType: 'json',
+        url: '/api/v1/get/mailbox/all',
+        jsonp: false,
+        error: function () {
+          alert('Cannot draw mailbox table');
         },
-        "sorting": {
-          "enabled": true
-        }
-      });
-    }
-  });
+        success: function (data) {
+          $.each(data, function (i, item) {
+            item.quota = item.quota_used + "/" + item.quota;
+            item.max_quota_for_mbox = humanFileSize(item.max_quota_for_mbox);
+            item.chkbox = '<input type="checkbox" data-id="mailbox" name="multi_select" value="' + item.username + '" />';
+            if (role == "admin") {
+            item.action = '<div class="btn-group">' +
+              '<a href="/edit.php?mailbox=' + encodeURI(item.username) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
+              '<a href="/delete.php?mailbox=' + encodeURI(item.username) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
+              '<a href="/index.php?duallogin=' + encodeURI(item.username) + '" class="btn btn-xs btn-success"><span class="glyphicon glyphicon-user"></span> Login</a>' +
+              '</div>';
+            }
+            else {
+            item.action = '<div class="btn-group">' +
+              '<a href="/edit.php?mailbox=' + encodeURI(item.username) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
+              '<a href="/delete.php?mailbox=' + encodeURI(item.username) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
+              '</div>';
+            }
+            item.in_use = '<div class="progress">' +
+              '<div class="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>';
 
-  $.ajax({
-    dataType: 'json',
-    url: '/api/v1/get/alias/all',
-    jsonp: false,
-    error: function () {
-      alert('Cannot draw alias table');
-    },
-    success: function (data) {
-      $.each(data, function (i, item) {
-        item.action = '<div class="btn-group">' +
-          '<a href="/edit.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
-          '<a href="/delete.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-pencil"></span> ' + lang.remove + '</a>' +
-					'</div>';
-        item.chkbox = '<input type="checkbox" class="alias_item" name="sel_aliases" value="' + item.address + '" />';
-        if (item.is_catch_all == 1) {
-          item.address = '<div class="label label-default">Catch-All</div> ' + item.address;
-        }
-        if (item.in_primary_domain !== "") {
-          item.domain = "↳ " + item.domain + " (" + item.in_primary_domain + ")";
+          });
         }
-      });
-      ft_aliases = FooTable.init("#alias_table", {
-        "columns": [
-          {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
-          {"sorted": true,"name":"address","title":lang.alias,"style":{"width":"250px"}},
-          {"name":"goto","title":lang.target_address},
-          {"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
-          {"name":"active","filterable": false,"style":{"maxWidth":"50px","width":"70px"},"title":lang.active},
-          {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
-        ],
-        "empty": lang.empty,
-        "rows": data,
-        "paging": {
-          "enabled": true,
-          "limit": 5,
-          "size": pagination_size
-        },
-        "filtering": {
-          "enabled": true,
-          "position": "left",
-          "placeholder": lang.filter_table
+      }),
+      "paging": {
+        "enabled": true,
+        "limit": 5,
+        "size": pagination_size
+      },
+      "filtering": {
+        "enabled": true,
+        "position": "left",
+        "placeholder": lang.filter_table
+      },
+      "sorting": {
+        "enabled": true
+      }
+    });
+  }
+  function draw_resource_table() {
+    ft_resource_table = FooTable.init('#resource_table', {
+      "columns": [
+        {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
+        {"sorted": true,"name":"description","title":lang.description,"style":{"width":"250px"}},
+        {"name":"kind","title":lang.kind},
+        {"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
+        {"name":"multiple_bookings","filterable": false,"style":{"maxWidth":"120px","width":"120px"},"title":lang.multiple_bookings,"breakpoints":"xs sm"},
+        {"name":"active","filterable": false,"style":{"maxWidth":"80px","width":"80px"},"title":lang.active},
+        {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
+      ],
+      "empty": lang.empty,
+      "rows": $.ajax({
+        dataType: 'json',
+        url: '/api/v1/get/resource/all',
+        jsonp: false,
+        error: function () {
+          alert('Cannot draw resource table');
         },
-        "sorting": {
-          "enabled": true
-        }
-      });
-
-      var selected_aliases = [];
-
-      $(document).on('click', 'tr', function(e) {
-        if (e.target.type == "checkbox") {
-          e.stopPropagation();
-        } else {
-          var checkbox = $(this).find(':checkbox');
-          checkbox.trigger('click');
-        }
-      });
-
-      $(document).on('change', 'input[name=sel_aliases]:checkbox', function() {
-        if ($(this).is(':checked')) {
-          selected_aliases.push($(this).val());
-        }
-        else {
-          selected_aliases.splice($.inArray($(this).val(), selected_aliases),1);
-        }
-      });
-
-      $(document).on('click', '#select_all_aliases', function(e) {
-        e.preventDefault();
-        var alias_chkbxs = $("input[name=sel_aliases]");
-        alias_chkbxs.prop("checked", !alias_chkbxs.prop("checked")).change();
-      });
-
-      $(document).on('click', '#activate_selected_alias', function(e) {
-        e.preventDefault();
-        if (Object.keys(selected_aliases).length !== 0) {
-          $.ajax({
-            type: "POST",
-            dataType: "json",
-            data: { "address": JSON.stringify(selected_aliases), "active": "1" },
-            url: '/api/v1/edit/alias',
-            jsonp: false,
-            complete: function (data) {
-              window.location.href = window.location.href;
-            }
+        success: function (data) {
+          $.each(data, function (i, item) {
+            item.action = '<div class="btn-group">' +
+              '<a href="/edit.php?resource=' + encodeURI(item.name) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
+              '<a href="/delete.php?resource=' + encodeURI(item.name) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
+              '</div>';
+            item.chkbox = '<input type="checkbox" data-id="resource" name="multi_select" value="' + item.name + '" />';
           });
         }
-      });
+      }),
+      "paging": {
+        "enabled": true,
+        "limit": 5,
+        "size": pagination_size
+      },
+      "filtering": {
+        "enabled": true,
+        "position": "left",
+        "placeholder": lang.filter_table
+      },
+      "sorting": {
+        "enabled": true
+      }
+    });
+  }
 
-      $(document).on('click', '#deactivate_selected_alias', function(e) {
-        e.preventDefault();
-        if (Object.keys(selected_aliases).length !== 0) {
-          $.ajax({
-            type: "POST",
-            dataType: "json",
-            data: { "address": JSON.stringify(selected_aliases), "active": "0" },
-            url: '/api/v1/edit/alias',
-            jsonp: false,
-            complete: function (data) {
-              window.location.href = window.location.href;
+  function draw_alias_table() {
+    ft_alias_table = FooTable.init('#alias_table', {
+      "columns": [
+        {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
+        {"sorted": true,"name":"address","title":lang.alias,"style":{"width":"250px"}},
+        {"name":"goto","title":lang.target_address},
+        {"name":"domain","title":lang.domain,"breakpoints":"xs sm"},
+        {"name":"active","filterable": false,"style":{"maxWidth":"50px","width":"70px"},"title":lang.active},
+        {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
+      ],
+      "empty": lang.empty,
+      "rows": $.ajax({
+        dataType: 'json',
+        url: '/api/v1/get/alias/all',
+        jsonp: false,
+        error: function () {
+          alert('Cannot draw alias table');
+        },
+        success: function (data) {
+          $.each(data, function (i, item) {
+            item.action = '<div class="btn-group">' +
+              '<a href="/edit.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
+              '<a href="/delete.php?alias=' + encodeURI(item.address) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-pencil"></span> ' + lang.remove + '</a>' +
+              '</div>';
+            item.chkbox = '<input type="checkbox" data-id="alias" name="multi_select" value="' + item.address + '" />';
+            if (item.is_catch_all == 1) {
+              item.address = '<div class="label label-default">Catch-All</div> ' + item.address;
+            }
+            if (item.in_primary_domain !== "") {
+              item.domain = "↳ " + item.domain + " (" + item.in_primary_domain + ")";
             }
           });
         }
-      });
-
-      $(document).on('click', '#delete_selected_alias', function(e) {
-        e.preventDefault();
-        if (Object.keys(selected_aliases).length !== 0) {
-          $(document).on('show.bs.modal','#ConfirmDeleteModal', function () {
-            $("#ItemsToDelete").empty();
-            for (var i in selected_aliases) {
-              $("#ItemsToDelete").append("<li>" + selected_aliases[i] + "</li>");
-            }
-          })
-          $('#ConfirmDeleteModal').modal({
-            backdrop: 'static',
-            keyboard: false
-          })
-          .one('click', '#IsConfirmed', function(e) {
-            $.ajax({
-              type: "POST",
-              dataType: "json",
-              data: { "address": JSON.stringify(selected_aliases) },
-              url: '/api/v1/delete/alias',
-              jsonp: false,
-              complete: function (data) {
-              window.location.href = window.location.href;
-              }
-            });
-          })
-          .one('click', '#isCanceled', function(e) {
-            $('#ConfirmDeleteModal').modal('hide');
-          });;
+      }),
+      "paging": {
+        "enabled": true,
+        "limit": 5,
+        "size": pagination_size
+      },
+      "filtering": {
+        "enabled": true,
+        "position": "left",
+        "placeholder": lang.filter_table
+      },
+      "sorting": {
+        "enabled": true
+      }
+    });
+  }
 
+  function draw_aliasdomain_table() {
+    ft_aliasdomain_table = FooTable.init('#aliasdomain_table', {
+      "columns": [
+        {"name":"chkbox","title":"","style":{"maxWidth":"40px","width":"40px"},"filterable": false,"sortable": false,"type":"html"},
+        {"sorted": true,"name":"alias_domain","title":lang.alias,"style":{"width":"250px"}},
+        {"name":"target_domain","title":lang.target_domain},
+        {"name":"active","filterable": false,"style":{"maxWidth":"50px","width":"70px"},"title":lang.active},
+        {"name":"action","filterable": false,"sortable": false,"style":{"text-align":"right","maxWidth":"180px","width":"180px"},"type":"html","title":lang.action,"breakpoints":"xs sm"}
+      ],
+      "empty": lang.empty,
+      "rows": $.ajax({
+        dataType: 'json',
+        url: '/api/v1/get/alias-domain/all',
+        jsonp: false,
+        error: function () {
+          alert('Cannot draw alias domain table');
+        },
+        success: function (data) {
+          $.each(data, function (i, item) {
+            item.action = '<div class="btn-group">' +
+              '<a href="/edit.php?aliasdomain=' + encodeURI(item.alias_domain) + '" class="btn btn-xs btn-default"><span class="glyphicon glyphicon-pencil"></span> ' + lang.edit + '</a>' +
+              '<a href="/delete.php?aliasdomain=' + encodeURI(item.alias_domain) + '" class="btn btn-xs btn-danger"><span class="glyphicon glyphicon-trash"></span> ' + lang.remove + '</a>' +
+              '</div>';
+            item.chkbox = '<input type="checkbox" data-id="alias-domain" name="multi_select" value="' + item.alias_domain + '" />';
+          });
         }
-      });
-
-    }
+      }),
+      "paging": {
+        "enabled": true,
+        "limit": 5,
+        "size": pagination_size
+      },
+      "filtering": {
+        "enabled": true,
+        "position": "left",
+        "placeholder": lang.filter_table
+      },
+      "sorting": {
+        "enabled": true
+      }
+    });
+  }
 
-  });
-});
+  draw_domain_table();
+  draw_mailbox_table();
+  draw_resource_table();
+  draw_alias_table();
+  draw_aliasdomain_table();
+});

File diff suppressed because it is too large
+ 0 - 0
data/web/js/notify.min.js


File diff suppressed because it is too large
+ 0 - 0
data/web/js/noty.min.js


+ 435 - 60
data/web/json_api.php

@@ -356,18 +356,6 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
               return;
             }
           break;
-          case "csrf-cookie":
-            if (isset($_SESSION['mailcow_cc_username']) && isset($_SESSION['mailcow_cc_role'])) {
-              csrfprotector::refreshToken();
-              echo json_encode(array(
-                'type' => 'success',
-                'msg' => 'Cookie refreshed'
-              ));
-            }
-            else {
-              return;
-            }
-          break;
           default:
             echo '{}';
           break;
@@ -376,10 +364,10 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
       case "delete":
         switch ($category) {
           case "alias":
-            if (isset($_POST['address'])) {
-              $address = json_decode($_POST['address'], true);
-              if (is_array($address)) {
-                if (mailbox_delete_alias(array('address' => $address)) === false) {
+            if (isset($_POST['items'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              if (is_array($items)) {
+                if (mailbox_delete_alias(array('address' => $items)) === false) {
                   if (isset($_SESSION['return'])) {
                     echo json_encode($_SESSION['return']);
                   }
@@ -389,25 +377,38 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
                       'msg' => 'Deletion of items/s failed'
                     ));
                   }
-                  exit();
-                }
-                if (isset($_SESSION['return'])) {
-                  echo json_encode($_SESSION['return']);
                 }
                 else {
-                  echo json_encode(array(
-                    'type' => 'success',
-                    'msg' => 'Item/s deleted: ' . $domains
-                  ));
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
                 }
               }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Cannot find address array in post data'
+                ));
+              }
+            }
+            else {
+              echo json_encode(array(
+                'type' => 'error',
+                'msg' => 'Cannot find items in post data'
+              ));
             }
           break;
           case "fwdhost":
-            if (isset($_POST['forwardinghost'])) {
-              $forwardinghost = (array)json_decode($_POST['forwardinghost'], true);
-              if (is_array($forwardinghost)) {
-                if (delete_forwarding_host(array('forwardinghost' => $forwardinghost)) === false) {
+            if (isset($_POST['items'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              if (is_array($items)) {
+                if (delete_forwarding_host(array('forwardinghost' => $items)) === false) {
                   if (isset($_SESSION['return'])) {
                     echo json_encode($_SESSION['return']);
                   }
@@ -417,31 +418,38 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
                       'msg' => 'Deletion of items/s failed'
                     ));
                   }
-                  exit();
-                }
-                if (isset($_SESSION['return'])) {
-                  echo json_encode($_SESSION['return']);
                 }
                 else {
-                  echo json_encode(array(
-                    'type' => 'success',
-                    'msg' => 'Item/s deleted: ' . $domains
-                  ));
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
                 }
               }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Cannot find forwardinghost array in post data'
+                ));
+              }
             }
             else {
               echo json_encode(array(
                 'type' => 'error',
-                'msg' => 'Cannot find forwardinghost array in post data'
+                'msg' => 'Cannot find items in post data'
               ));
             }
           break;
           case "dkim":
-            if (isset($_POST['domains'])) {
-              $domains = (array)json_decode($_POST['domains'], true);
-              if (is_array($domains)) {
-                if (dkim_delete_key(array('domains' => $domains)) === false) {
+            if (isset($_POST['items'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              if (is_array($items)) {
+                if (dkim_delete_key(array('domains' => $items)) === false) {
                   if (isset($_SESSION['return'])) {
                     echo json_encode($_SESSION['return']);
                   }
@@ -451,23 +459,194 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
                       'msg' => 'Deletion of items/s failed'
                     ));
                   }
-                  exit();
                 }
-                if (isset($_SESSION['return'])) {
-                  echo json_encode($_SESSION['return']);
+                else {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
+                }
+              }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Cannot find domains array in post data'
+                ));
+              }
+            }
+            else {
+              echo json_encode(array(
+                'type' => 'error',
+                'msg' => 'Cannot find items in post data'
+              ));
+            }
+          break;
+          case "domain":
+            if (isset($_POST['items'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              if (is_array($items)) {
+                if (mailbox_delete_domain(array('domain' => $items)) === false) {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'error',
+                      'msg' => 'Task failed'
+                    ));
+                  }
+                }
+                else {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
+                }
+              }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Cannot find domain array in post data'
+                ));
+              }
+            }
+            else {
+              echo json_encode(array(
+                'type' => 'error',
+                'msg' => 'Cannot find items in post data'
+              ));
+            }
+          break;
+          case "alias-domain":
+            if (isset($_POST['items'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              if (is_array($items)) {
+                if (mailbox_delete_alias_domain(array('alias_domain' => $items)) === false) {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'error',
+                      'msg' => 'Task failed'
+                    ));
+                  }
+                }
+                else {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
+                }
+              }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Cannot find alias_domain array in post data'
+                ));
+              }
+            }
+            else {
+              echo json_encode(array(
+                'type' => 'error',
+                'msg' => 'Cannot find items in post data'
+              ));
+            }
+          break;
+          case "mailbox":
+            if (isset($_POST['items'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              if (is_array($items)) {
+                if (mailbox_delete_mailbox(array('username' => $items)) === false) {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'error',
+                      'msg' => 'Task failed'
+                    ));
+                  }
+                }
+                else {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
+                }
+              }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Cannot find username array in post data'
+                ));
+              }
+            }
+            else {
+              echo json_encode(array(
+                'type' => 'error',
+                'msg' => 'Cannot find items in post data'
+              ));
+            }
+          break;
+          case "resource":
+            if (isset($_POST['items'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              if (is_array($items)) {
+                if (mailbox_delete_resource(array('name' => $items)) === false) {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'error',
+                      'msg' => 'Task failed'
+                    ));
+                  }
                 }
                 else {
-                  echo json_encode(array(
-                    'type' => 'success',
-                    'msg' => 'Item/s deleted: ' . $domains
-                  ));
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
                 }
               }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Cannot find name array in post data'
+                ));
+              }
             }
             else {
               echo json_encode(array(
                 'type' => 'error',
-                'msg' => 'Cannot find domains array in post data'
+                'msg' => 'Cannot find items in post data'
               ));
             }
           break;
@@ -476,26 +655,222 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
       case "edit":
         switch ($category) {
           case "alias":
-            if (isset($_POST['address']) && isset($_POST['active'])) {
-              $address = (array)json_decode($_POST['address'], true);
-              if (is_array($address)) {
-                if (mailbox_edit_alias(array('address' => $address, 'active' => ($_POST['active'] == "1") ? $active = 1 : null)) === false) {
-                  echo json_encode(array(
-                    'type' => 'error',
-                    'msg' => 'Edit item failed'
-                  ));
+            if (isset($_POST['items']) && isset($_POST['attr'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              $attr = (array)json_decode($_POST['attr'], true);
+              $postarray = array_merge(array('address' => $items), $attr);
+              if (is_array($postarray['address'])) {
+                if (mailbox_edit_alias($postarray) === false) {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'error',
+                      'msg' => 'Edit failed'
+                    ));
+                  }
+                  exit();
+                }
+                else {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
+                }
+              }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Incomplete post data'
+                ));
+              }
+            }
+            else {
+              echo json_encode(array(
+                'type' => 'error',
+                'msg' => 'Incomplete post data'
+              ));
+            }
+          break;
+          case "mailbox":
+            if (isset($_POST['items']) && isset($_POST['attr'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              $attr = (array)json_decode($_POST['attr'], true);
+              $postarray = array_merge(array('username' => $items), $attr);
+              if (is_array($postarray['username'])) {
+                if (mailbox_edit_mailbox($postarray) === false) {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'error',
+                      'msg' => 'Edit failed'
+                    ));
+                  }
+                  exit();
+                }
+                else {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
+                }
+              }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Incomplete post data'
+                ));
+              }
+            }
+            else {
+              echo json_encode(array(
+                'type' => 'error',
+                'msg' => 'Incomplete post data'
+              ));
+            }
+          break;
+          case "resource":
+            if (isset($_POST['items']) && isset($_POST['attr'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              $attr = (array)json_decode($_POST['attr'], true);
+              $postarray = array_merge(array('name' => $items), $attr);
+              if (is_array($postarray['name'])) {
+                if (mailbox_edit_resource($postarray) === false) {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'error',
+                      'msg' => 'Edit failed'
+                    ));
+                  }
                   exit();
                 }
+                else {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
+                }
+              }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Incomplete post data'
+                ));
+              }
+            }
+            else {
+              echo json_encode(array(
+                'type' => 'error',
+                'msg' => 'Incomplete post data'
+              ));
+            }
+          break;
+          case "domain":
+            if (isset($_POST['items']) && isset($_POST['attr'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              $attr = (array)json_decode($_POST['attr'], true);
+              $postarray = array_merge(array('domain' => $items), $attr);
+              if (is_array($postarray['domain'])) {
+                if (mailbox_edit_domain($postarray) === false) {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'error',
+                      'msg' => 'Edit failed'
+                    ));
+                  }
+                  exit();
+                }
+                else {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
+                }
+              }
+              else {
+                echo json_encode(array(
+                  'type' => 'error',
+                  'msg' => 'Incomplete post data'
+                ));
+              }
+            }
+            else {
+              echo json_encode(array(
+                'type' => 'error',
+                'msg' => 'Incomplete post data'
+              ));
+            }
+          break;
+          case "alias-domain":
+            if (isset($_POST['items']) && isset($_POST['attr'])) {
+              $items = (array)json_decode($_POST['items'], true);
+              $attr = (array)json_decode($_POST['attr'], true);
+              $postarray = array_merge(array('alias_domain' => $items), $attr);
+              if (is_array($postarray['alias_domain'])) {
+                if (mailbox_edit_alias_domain($postarray) === false) {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'error',
+                      'msg' => 'Edit failed'
+                    ));
+                  }
+                  exit();
+                }
+                else {
+                  if (isset($_SESSION['return'])) {
+                    echo json_encode($_SESSION['return']);
+                  }
+                  else {
+                    echo json_encode(array(
+                      'type' => 'success',
+                      'msg' => 'Task completed'
+                    ));
+                  }
+                }
+              }
+              else {
                 echo json_encode(array(
-                  'type' => 'success',
-                  'msg' => 'Task completed'
+                  'type' => 'error',
+                  'msg' => 'Incomplete post data'
                 ));
               }
             }
             else {
               echo json_encode(array(
                 'type' => 'error',
-                'msg' => 'Cannot find address array in post data'
+                'msg' => 'Incomplete post data'
               ));
             }
           break;

+ 2 - 2
data/web/lang/lang.de.php

@@ -70,12 +70,12 @@ $lang['danger']['login_failed'] = 'Anmeldung fehlgeschlagen';
 $lang['danger']['mailbox_invalid'] = 'Mailboxname ist ungültig';
 $lang['danger']['resource_invalid'] = 'Ressourcenname ist ungültig';
 $lang['danger']['description_invalid'] = 'Ressourcenbeschreibung ist ungültig';
-$lang['danger']['mailbox_invalid_suggest'] = 'Mailboxname ist ungültig, meinten Sie vielleicht "%s"?';
+$lang['danger']['mailbox_invalid_suggest'] = 'Mailboxname ist ungültig, meinten Sie vielleicht %s?';
 $lang['danger']['is_alias'] = '%s lautet bereits eine Alias-Adresse';
 $lang['danger']['is_alias_or_mailbox'] = "Eine Mailbox oder ein Alias mit der Adresse %s ist bereits vorhanden";
 $lang['danger']['is_spam_alias'] = '%s lautet bereits eine Spam-Alias-Adresse';
 $lang['danger']['quota_not_0_not_numeric'] = 'Speicherplatz muss numerisch und >= 0 sein';
-$lang['danger']['domain_not_found'] = 'Domain "%s" nicht gefunden.';
+$lang['danger']['domain_not_found'] = 'Domain %s nicht gefunden';
 $lang['danger']['max_mailbox_exceeded'] = 'Anzahl an Mailboxen überschritten (%d von %d)';
 $lang['danger']['max_alias_exceeded'] = 'Anzahl an Alias-Adressen überschritten';
 $lang['danger']['mailbox_quota_exceeded'] = 'Speicherplatz überschreitet das Limit (max. %d MiB)';

+ 1 - 1
data/web/lang/lang.en.php

@@ -77,7 +77,7 @@ $lang['danger']['is_alias'] = "%s is already known as an alias address";
 $lang['danger']['is_alias_or_mailbox'] = "%s is already known as an alias or a mailbox";
 $lang['danger']['is_spam_alias'] = "%s is already known as a spam alias address";
 $lang['danger']['quota_not_0_not_numeric'] = "Quota must be numeric and >= 0";
-$lang['danger']['domain_not_found'] = "Domain not found.";
+$lang['danger']['domain_not_found'] = 'Domain "%s" not found';
 $lang['danger']['max_mailbox_exceeded'] = "Max. mailboxes exceeded (%d of %d)";
 $lang['danger']['max_alias_exceeded'] = 'Max. aliases exceeded';
 $lang['danger']['mailbox_quota_exceeded'] = "Quota exceeds the domain limit (max. %d MiB)";

+ 62 - 13
data/web/mailbox.php

@@ -31,16 +31,28 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
             <?php
             if ($_SESSION['mailcow_cc_role'] == "admin"):
             ?>
-              <a href="/add.php?domain"><span class="glyphicon glyphicon-plus"></span></a>
+            <a href="/add.php?domain"><span class="glyphicon glyphicon-plus"></span></a></li>
             <?php
             endif;
             ?>
             </div>
-            <h3 class="panel-title"><?=$lang['mailbox']['domains'];?></h3>
+            <?=$lang['mailbox']['domains'];?>
             </div>
             <div class="table-responsive">
               <table id="domain_table" class="table table-striped"></table>
             </div>
+            <div class="mass-actions-mailbox">
+              <div class="btn-group">
+                <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="domain" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+                <a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
+                <ul class="dropdown-menu">
+                  <li><a id="edit_selected" data-id="domain" data-api-url='edit/domain' data-api-attr='{"active":"1"}' href="#"><?=$lang['mailbox']['activate'];?></a></li>
+                  <li><a id="edit_selected" data-id="domain" data-api-url='edit/domain' data-api-attr='{"active":"0"}' href="#"><?=$lang['mailbox']['deactivate'];?></a></li>
+                  <li role="separator" class="divider"></li>
+                  <li><a id="delete_selected" data-id="domain" data-api-url='delete/domain' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+                </ul>
+              </div>
+            </div>
             <span class="footer-add-item"><a href="/add.php?domain"><?=$lang['mailbox']['add_domain'];?></a></span>
           </div>
         </div>
@@ -56,6 +68,18 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
             <div class="table-responsive">
               <table id="mailbox_table" class="table table-striped"></table>
             </div>
+            <div class="mass-actions-mailbox">
+              <div class="btn-group">
+                <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="mailbox" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+                <a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
+                <ul class="dropdown-menu">
+                  <li><a id="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"active":"1"}' href="#"><?=$lang['mailbox']['activate'];?></a></li>
+                  <li><a id="edit_selected" data-id="mailbox" data-api-url='edit/mailbox' data-api-attr='{"active":"0"}' href="#"><?=$lang['mailbox']['deactivate'];?></a></li>
+                  <li role="separator" class="divider"></li>
+                  <li><a id="delete_selected" data-id="mailbox" data-api-url='delete/mailbox' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+                </ul>
+              </div>
+            </div>
             <span class="footer-add-item"><a href="/add.php?mailbox"><?=$lang['mailbox']['add_mailbox'];?></a></span>
           </div>
         </div>
@@ -71,6 +95,18 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
             <div class="table-responsive">
               <table id="resources_table" class="table table-striped"></table>
             </div>
+            <div class="mass-actions-mailbox">
+              <div class="btn-group">
+                <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="resource" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+                <a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
+                <ul class="dropdown-menu">
+                  <li><a id="edit_selected" data-id="resource" data-api-url='edit/resource' data-api-attr='{"active":"1"}' href="#"><?=$lang['mailbox']['activate'];?></a></li>
+                  <li><a id="edit_selected" data-id="resource" data-api-url='edit/resource' data-api-attr='{"active":"0"}' href="#"><?=$lang['mailbox']['deactivate'];?></a></li>
+                  <li role="separator" class="divider"></li>
+                  <li><a id="delete_selected" data-id="resource" data-api-url='delete/resource' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+                </ul>
+              </div>
+            </div>
             <span class="footer-add-item"><a href="/add.php?resource"><?=$lang['mailbox']['add_resource'];?></a></span>
           </div>
         </div>
@@ -86,6 +122,18 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
             <div class="table-responsive">
               <table id="aliasdomain_table" class="table table-striped"></table>
             </div>
+            <div class="mass-actions-mailbox">
+              <div class="btn-group">
+                <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="alias-domain" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+                <a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
+                <ul class="dropdown-menu">
+                  <li><a id="edit_selected" data-id="alias-domain" data-api-url='edit/alias-domain' data-api-attr='{"active":"1"}' href="#"><?=$lang['mailbox']['activate'];?></a></li>
+                  <li><a id="edit_selected" data-id="alias-domain" data-api-url='edit/alias-domain' data-api-attr='{"active":"0"}' href="#"><?=$lang['mailbox']['deactivate'];?></a></li>
+                  <li role="separator" class="divider"></li>
+                  <li><a id="delete_selected" data-id="alias-domain" data-api-url='delete/alias-domain' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+                </ul>
+              </div>
+            </div>
             <span class="footer-add-item"><a href="/add.php?aliasdomain"><?=$lang['mailbox']['add_domain_alias'];?></a></span>
           </div>
         </div>
@@ -99,18 +147,19 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
             <div class="table-responsive">
               <table id="alias_table" class="table table-striped"></table>
             </div>
-            <div class="mass-actions">
-              <p id="select_all_aliases" class="mass-select-all">
-                ↪ <?=$lang['mailbox']['toggle_all'];?>
-              </p>
-            </div>
-            <div class="footer-add-item">
-              <a class="pull-right" href="/add.php?alias"><span class="glyphicon glyphicon-plus"></span></a>
-              <b><?=$lang['mailbox']['quick_actions'];?>:</b>
-              <a id="delete_selected_alias" href="#" class="mass-each-action"><?=$lang['mailbox']['remove'];?></a> |
-              <a id="activate_selected_alias" href="#" class="mass-each-action"><?=$lang['mailbox']['activate'];?></a> |
-              <a id="deactivate_selected_alias" href="#" class="mass-each-action"><?=$lang['mailbox']['deactivate'];?></a>
+            <div class="mass-actions-mailbox">
+              <div class="btn-group">
+                <a class="btn btn-sm btn-default" id="toggle_multi_select_all" data-id="alias" href="#"><span class="glyphicon glyphicon-check" aria-hidden="true"></span> <?=$lang['mailbox']['toggle_all'];?></a>
+                <a class="btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" href="#"><?=$lang['mailbox']['quick_actions'];?> <span class="caret"></span></a>
+                <ul class="dropdown-menu">
+                  <li><a id="edit_selected" data-id="alias" data-api-url='edit/alias' data-api-attr='{"active":"1","active1":"12"}' href="#"><?=$lang['mailbox']['activate'];?></a></li>
+                  <li><a id="edit_selected" data-id="alias" data-api-url='edit/alias' data-api-attr='{"active":"0"}' href="#"><?=$lang['mailbox']['deactivate'];?></a></li>
+                  <li role="separator" class="divider"></li>
+                  <li><a id="delete_selected" data-id="alias" data-api-url='delete/alias' href="#"><?=$lang['mailbox']['remove'];?></a></li>
+                </ul>
+              </div>
             </div>
+            <span class="footer-add-item"><a href="/add.php?alias"><?=$lang['mailbox']['add_alias'];?></a></span>
           </div>
         </div>
 

+ 4 - 2
data/web/user.php

@@ -382,18 +382,20 @@ elseif (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == '
 	</div>
 	<div role="tabpanel" class="tab-pane" id="TLSPolicy">
 		<form class="form-horizontal" role="form" method="post">
+      <input type="hidden" value="0" name="tls_in">
+      <input type="hidden" value="0" name="tls_out">
 			<p class="help-block"><?=$lang['user']['tls_policy_warning'];?></p>
 			<div class="form-group">
 				<div class="col-sm-6">
 					<div class="checkbox">
 						<h4><span class="glyphicon glyphicon-download" aria-hidden="true"></span> <?=$lang['user']['tls_enforce_in'];?></h4>
-						<input type="checkbox" id="tls_in" name="tls_in" <?=($get_tls_policy['tls_enforce_in'] == "1") ? "checked" : null;?> data-on-text="<?=$lang['user']['on'];?>" data-off-text="<?=$lang['user']['off'];?>">
+						<input type="checkbox" value="1" id="tls_in" name="tls_in" <?=($get_tls_policy['tls_enforce_in'] == "1") ? "checked" : null;?> data-on-text="<?=$lang['user']['on'];?>" data-off-text="<?=$lang['user']['off'];?>">
 					</div>
 				</div>
 				<div class="col-sm-6">
 					<div class="checkbox">
 						<h4><span class="glyphicon glyphicon-upload" aria-hidden="true"></span> <?=$lang['user']['tls_enforce_out'];?></h4>
-						<input type="checkbox" id="tls_out" name="tls_out" <?=($get_tls_policy['tls_enforce_out'] == "1") ? "checked" : null;?> data-on-text="<?=$lang['user']['on'];?>" data-off-text="<?=$lang['user']['off'];?>">
+						<input type="checkbox" value="1" id="tls_out" name="tls_out" <?=($get_tls_policy['tls_enforce_out'] == "1") ? "checked" : null;?> data-on-text="<?=$lang['user']['on'];?>" data-off-text="<?=$lang['user']['off'];?>">
 					</div>
 				</div>
 			</div>

Some files were not shown because too many files changed in this diff