瀏覽代碼

[Web] Minor changes or fixes; [Web] Add multiple transport destinations at the same time - comma separated

andryyy 6 年之前
父節點
當前提交
ab42540769
共有 5 個文件被更改,包括 57 次插入46 次删除
  1. 1 1
      data/web/admin.php
  2. 38 36
      data/web/inc/functions.transports.inc.php
  3. 11 5
      data/web/js/site/admin.js
  4. 4 2
      data/web/lang/lang.de.php
  5. 3 2
      data/web/lang/lang.en.php

+ 1 - 1
data/web/admin.php

@@ -289,7 +289,7 @@ if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CAC
             <form class="form" data-id="transport" role="form" method="post">
             <form class="form" data-id="transport" role="form" method="post">
               <div class="form-group">
               <div class="form-group">
                 <label for="destination"><?=$lang['admin']['destination'];?></label>
                 <label for="destination"><?=$lang['admin']['destination'];?></label>
-                <input class="form-control input-sm" name="destination" placeholder='example.org, .example.org, *, box@example.org' required>
+                <input class="form-control input-sm" name="destination" placeholder='<?=$lang['admin']['transport_dest_format'];?>' required>
               </div>
               </div>
               <div class="form-group">
               <div class="form-group">
                 <label for="nexthop"><?=$lang['admin']['nexthop'];?></label>
                 <label for="nexthop"><?=$lang['admin']['nexthop'];?></label>

+ 38 - 36
data/web/inc/functions.transports.inc.php

@@ -186,7 +186,7 @@ function transport($_action, $_data = null) {
         );
         );
         return false;
         return false;
       }
       }
-      $destination = trim($_data['destination']);
+      $destinations  = array_map('trim', preg_split( "/( |,|;|\n)/", $_data['destination']));
       $active = intval($_data['active']);
       $active = intval($_data['active']);
       $lookup_mx = intval($_data['lookup_mx']);
       $lookup_mx = intval($_data['lookup_mx']);
       $nexthop = trim($_data['nexthop']);
       $nexthop = trim($_data['nexthop']);
@@ -194,15 +194,6 @@ function transport($_action, $_data = null) {
       $next_hop_clean = (isset($next_hop_matches[1])) ? $next_hop_matches[1] : $nexthop;
       $next_hop_clean = (isset($next_hop_matches[1])) ? $next_hop_matches[1] : $nexthop;
       $username = str_replace(':', '\:', trim($_data['username']));
       $username = str_replace(':', '\:', trim($_data['username']));
       $password = str_replace(':', '\:', trim($_data['password']));
       $password = str_replace(':', '\:', trim($_data['password']));
-      // ".domain" is a valid destination, "..domain" is not
-      if (empty($destination) || (is_valid_domain_name(preg_replace('/^' . preg_quote('.', '/') . '/', '', $destination)) === false && $destination != '*' && filter_var($destination, FILTER_VALIDATE_EMAIL) === false)) {
-        $_SESSION['return'][] = array(
-          'type' => 'danger',
-          'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => 'invalid_destination'
-        );
-        return false;
-      }
       if (empty($nexthop)) {
       if (empty($nexthop)) {
         $_SESSION['return'][] = array(
         $_SESSION['return'][] = array(
           'type' => 'danger',
           'type' => 'danger',
@@ -225,16 +216,35 @@ function transport($_action, $_data = null) {
             );
             );
             return false;
             return false;
           }
           }
-          if ($transport_data['destination'] == $destination) {
-            $_SESSION['return'][] = array(
-              'type' => 'danger',
-              'log' => array(__FUNCTION__, $_action, $_data_log),
-              'msg' => 'transport_dest_exists'
-            );
-            return false;
+          foreach ($destinations as $d_ix => &$dest) {
+            if (empty($dest)) {
+              unset($destinations[$d_ix]);
+              continue;
+            }
+            if ($transport_data['destination'] == $dest) {
+              $_SESSION['return'][] = array(
+                'type' => 'danger',
+                'log' => array(__FUNCTION__, $_action, $_data_log),
+                'msg' => array('transport_dest_exists', $dest)
+              );
+              unset($destinations[$d_ix]);
+              continue;
+            }
+            // ".domain" is a valid destination, "..domain" is not
+            if (empty($dest) || (is_valid_domain_name(preg_replace('/^' . preg_quote('.', '/') . '/', '', $dest)) === false && $dest != '*' && filter_var($dest, FILTER_VALIDATE_EMAIL) === false)) {
+              $_SESSION['return'][] = array(
+                'type' => 'danger',
+                'log' => array(__FUNCTION__, $_action, $_data_log),
+                'msg' => array('invalid_destination', $dest)
+              );
+              unset($destinations[$d_ix]);
+              continue;
+            }
           }
           }
         }
         }
       }
       }
+      $destinations = array_values($destinations);
+      if (empty($destinations)) { return false; }
       if (isset($next_hop_matches[1])) {
       if (isset($next_hop_matches[1])) {
         if (in_array($next_hop_clean, $existing_nh)) {
         if (in_array($next_hop_clean, $existing_nh)) {
           $_SESSION['return'][] = array(
           $_SESSION['return'][] = array(
@@ -257,35 +267,27 @@ function transport($_action, $_data = null) {
           }
           }
         }
         }
       }
       }
-      try {
+      foreach ($destinations as $insert_dest) {
         $stmt = $pdo->prepare("INSERT INTO `transports` (`nexthop`, `destination`, `username` , `password`,  `lookup_mx`, `active`)
         $stmt = $pdo->prepare("INSERT INTO `transports` (`nexthop`, `destination`, `username` , `password`,  `lookup_mx`, `active`)
           VALUES (:nexthop, :destination, :username, :password, :lookup_mx, :active)");
           VALUES (:nexthop, :destination, :username, :password, :lookup_mx, :active)");
         $stmt->execute(array(
         $stmt->execute(array(
           ':nexthop' => $nexthop,
           ':nexthop' => $nexthop,
-          ':destination' => $destination,
+          ':destination' => $insert_dest,
           ':username' => $username,
           ':username' => $username,
           ':password' => str_replace(':', '\:', $password),
           ':password' => str_replace(':', '\:', $password),
           ':lookup_mx' => $lookup_mx,
           ':lookup_mx' => $lookup_mx,
           ':active' => $active
           ':active' => $active
         ));
         ));
-        $stmt = $pdo->prepare("UPDATE `transports` SET
-          `username` = :username,
-          `password` = :password
-            WHERE `nexthop` = :nexthop");
-        $stmt->execute(array(
-          ':nexthop' => $nexthop,
-          ':username' => $username,
-          ':password' => $password
-        ));
-      }
-      catch (PDOException $e) {
-        $_SESSION['return'][] = array(
-          'type' => 'danger',
-          'log' => array(__FUNCTION__, $_action, $_data_log),
-          'msg' => array('mysql_error', $e)
-        );
-        return false;
       }
       }
+      $stmt = $pdo->prepare("UPDATE `transports` SET
+        `username` = :username,
+        `password` = :password
+          WHERE `nexthop` = :nexthop");
+      $stmt->execute(array(
+        ':nexthop' => $nexthop,
+        ':username' => $username,
+        ':password' => $password
+      ));
       $_SESSION['return'][] = array(
       $_SESSION['return'][] = array(
         'type' => 'success',
         'type' => 'success',
         'log' => array(__FUNCTION__, $_action, $_data_log),
         'log' => array(__FUNCTION__, $_action, $_data_log),

+ 11 - 5
data/web/js/site/admin.js

@@ -74,7 +74,8 @@ jQuery(function($){
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
       "state": {"enabled": true},
       "state": {"enabled": true},
       "filtering": {"enabled": true,"delay": 1,"position": "left","connectors": false,"placeholder": lang.filter_table},
       "filtering": {"enabled": true,"delay": 1,"position": "left","connectors": false,"placeholder": lang.filter_table},
-      "sorting": {"enabled": true}
+      "sorting": {"enabled": true},
+      "toggleSelector": "table tbody span.footable-toggle"
     });
     });
   }
   }
   function draw_admins() {
   function draw_admins() {
@@ -101,7 +102,8 @@ jQuery(function($){
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
       "filtering": {"enabled": false},
       "filtering": {"enabled": false},
       "state": {"enabled": true},
       "state": {"enabled": true},
-      "sorting": {"enabled": true}
+      "sorting": {"enabled": true},
+      "toggleSelector": "table tbody span.footable-toggle"
     });
     });
   }
   }
   function draw_fwd_hosts() {
   function draw_fwd_hosts() {
@@ -126,7 +128,8 @@ jQuery(function($){
       }),
       }),
       "empty": lang.empty,
       "empty": lang.empty,
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
-      "sorting": {"enabled": true}
+      "sorting": {"enabled": true},
+      "toggleSelector": "table tbody span.footable-toggle"
     });
     });
   }
   }
   function draw_relayhosts() {
   function draw_relayhosts() {
@@ -153,7 +156,8 @@ jQuery(function($){
       }),
       }),
       "empty": lang.empty,
       "empty": lang.empty,
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
-      "sorting": {"enabled": true}
+      "sorting": {"enabled": true},
+      "toggleSelector": "table tbody span.footable-toggle"
     });
     });
   }
   }
   function draw_transport_maps() {
   function draw_transport_maps() {
@@ -180,7 +184,8 @@ jQuery(function($){
       }),
       }),
       "empty": lang.empty,
       "empty": lang.empty,
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
-      "sorting": {"enabled": true}
+      "sorting": {"enabled": true},
+      "toggleSelector": "table tbody span.footable-toggle"
     });
     });
   }
   }
   function draw_queue() {
   function draw_queue() {
@@ -210,6 +215,7 @@ jQuery(function($){
       "empty": lang.empty,
       "empty": lang.empty,
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
       "paging": {"enabled": true,"limit": 5,"size": log_pagination_size},
       "sorting": {"enabled": true},
       "sorting": {"enabled": true},
+      "toggleSelector": "table tbody span.footable-toggle",
       "on": {
       "on": {
         "ready.ft.table": function(e, ft){
         "ready.ft.table": function(e, ft){
           table_admin_ready(ft, 'queuetable');
           table_admin_ready(ft, 'queuetable');

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

@@ -19,7 +19,7 @@ $lang['footer']['cancel'] = 'Abbrechen';
 $lang['footer']['hibp_nok'] = 'Übereinstimmung gefunden! Dieses Passwort ist potentiell gefährlich!';
 $lang['footer']['hibp_nok'] = 'Übereinstimmung gefunden! Dieses Passwort ist potentiell gefährlich!';
 $lang['footer']['hibp_ok'] = 'Keine Übereinstimmung gefunden.';
 $lang['footer']['hibp_ok'] = 'Keine Übereinstimmung gefunden.';
 
 
-$lang['danger']['transport_dest_exists'] = "Transport Maps Ziel existiert bereits";
+$lang['danger']['transport_dest_exists'] = 'Transport Maps Ziel "%s" existiert bereits';
 $lang['danger']['unlimited_quota_acl'] = "Unendliche Quota untersagt durch ACL";
 $lang['danger']['unlimited_quota_acl'] = "Unendliche Quota untersagt durch ACL";
 $lang['danger']['mysql_error'] = "MySQL Fehler: %s";
 $lang['danger']['mysql_error'] = "MySQL Fehler: %s";
 $lang['danger']['redis_error'] = "Redis Fehler: %s";
 $lang['danger']['redis_error'] = "Redis Fehler: %s";
@@ -31,7 +31,7 @@ $lang['success']['verified_u2f_login'] = "U2F Anmeldung verifiziert";
 $lang['success']['verified_yotp_login'] = "Yubico OTP Anmeldung verifiziert";
 $lang['success']['verified_yotp_login'] = "Yubico OTP Anmeldung verifiziert";
 $lang['danger']['yotp_verification_failed'] = "Yubico OTP Verifizierung fehlgeschlagen: %s";
 $lang['danger']['yotp_verification_failed'] = "Yubico OTP Verifizierung fehlgeschlagen: %s";
 $lang['danger']['ip_list_empty'] = "Liste erlaubter IPs darf nicht leer sein";
 $lang['danger']['ip_list_empty'] = "Liste erlaubter IPs darf nicht leer sein";
-$lang['danger']['invalid_destination'] = "Ziel-Format ist ungültig";
+$lang['danger']['invalid_destination'] = 'Ziel-Format "%s" ist ungültig';
 $lang['danger']['invalid_nexthop'] = "Next Hop ist ungültig";
 $lang['danger']['invalid_nexthop'] = "Next Hop ist ungültig";
 $lang['danger']['invalid_nexthop_authenticated'] = 'Dieser Next Hop existiert bereits mit abweichenden Authentifizierungsdaten. Die bestehenden Authentifizierungsdaten dieses "Next Hops" müssen vorab angepasst werden.';
 $lang['danger']['invalid_nexthop_authenticated'] = 'Dieser Next Hop existiert bereits mit abweichenden Authentifizierungsdaten. Die bestehenden Authentifizierungsdaten dieses "Next Hops" müssen vorab angepasst werden.';
 $lang['danger']['next_hop_interferes'] = "%s verhindert das Hinzufügen von Next Hop %s";
 $lang['danger']['next_hop_interferes'] = "%s verhindert das Hinzufügen von Next Hop %s";
@@ -857,3 +857,5 @@ $lang['edit']['mbox_rl_info'] = 'Dieses Limit wird auf den SASL Loginnamen angew
 
 
 $lang['add']['relayhost_wrapped_tls_info'] = 'Bitte <b>keine</b> TLS-wrapped Ports verwenden (etwa SMTPS via Port 465/tcp).<br>
 $lang['add']['relayhost_wrapped_tls_info'] = 'Bitte <b>keine</b> TLS-wrapped Ports verwenden (etwa SMTPS via Port 465/tcp).<br>
 Der Transport wird stattdessen STARTTLS anfordern, um TLS zu verwenden. TLS kann unter "TLS Policy Maps" erzwungen werden.';
 Der Transport wird stattdessen STARTTLS anfordern, um TLS zu verwenden. TLS kann unter "TLS Policy Maps" erzwungen werden.';
+
+$lang['admin']['transport_dest_format'] = 'Syntax: example.org, .example.org, *, box@example.org (mehrere Werte getrennt durch Komma einzugeben)';

+ 3 - 2
data/web/lang/lang.en.php

@@ -20,7 +20,7 @@ $lang['footer']['cancel'] = 'Cancel';
 $lang['footer']['hibp_nok'] = 'Matched! This is a potentially dangerous password!';
 $lang['footer']['hibp_nok'] = 'Matched! This is a potentially dangerous password!';
 $lang['footer']['hibp_ok'] = 'No match found.';
 $lang['footer']['hibp_ok'] = 'No match found.';
 
 
-$lang['danger']['transport_dest_exists'] = "Transport destination exists";
+$lang['danger']['transport_dest_exists'] = 'Transport destination "%s" exists';
 $lang['danger']['unlimited_quota_acl'] = "Unlimited quota prohibited by ACL";
 $lang['danger']['unlimited_quota_acl'] = "Unlimited quota prohibited by ACL";
 $lang['danger']['mysql_error'] = "MySQL error: %s";
 $lang['danger']['mysql_error'] = "MySQL error: %s";
 $lang['danger']['redis_error'] = "Redis error: %s";
 $lang['danger']['redis_error'] = "Redis error: %s";
@@ -32,7 +32,7 @@ $lang['success']['verified_u2f_login'] = "Verified U2F login";
 $lang['success']['verified_yotp_login'] = "Verified Yubico OTP login";
 $lang['success']['verified_yotp_login'] = "Verified Yubico OTP login";
 $lang['danger']['yotp_verification_failed'] = "Yubico OTP verification failed: %s";
 $lang['danger']['yotp_verification_failed'] = "Yubico OTP verification failed: %s";
 $lang['danger']['ip_list_empty'] = "List of allowed IPs cannot be empty";
 $lang['danger']['ip_list_empty'] = "List of allowed IPs cannot be empty";
-$lang['danger']['invalid_destination'] = "Destination format is invalid";
+$lang['danger']['invalid_destination'] = 'Destination format "%s" is invalid';
 $lang['danger']['invalid_nexthop'] = "Next hop format is invalid";
 $lang['danger']['invalid_nexthop'] = "Next hop format is invalid";
 $lang['danger']['invalid_nexthop_authenticated'] = "Next hop exists with different credentials, please update the existing credentials for this next hop first.";
 $lang['danger']['invalid_nexthop_authenticated'] = "Next hop exists with different credentials, please update the existing credentials for this next hop first.";
 $lang['danger']['next_hop_interferes'] = "%s interferes with nexthop %s";
 $lang['danger']['next_hop_interferes'] = "%s interferes with nexthop %s";
@@ -887,3 +887,4 @@ $lang['edit']['mbox_rl_info'] = 'This rate limit is applied on the SASL login na
 $lang['add']['relayhost_wrapped_tls_info'] = 'Please do <b>not</b> use TLS-wrapped ports (mostly used on port 465).<br>
 $lang['add']['relayhost_wrapped_tls_info'] = 'Please do <b>not</b> use TLS-wrapped ports (mostly used on port 465).<br>
 Use any non-wrapped port and issue STARTTLS. A TLS policy to enforce TLS can be created in "TLS policy maps".';
 Use any non-wrapped port and issue STARTTLS. A TLS policy to enforce TLS can be created in "TLS policy maps".';
 
 
+$lang['admin']['transport_dest_format'] = 'Syntax: example.org, .example.org, *, box@example.org (multiple values can be comma-separated)';