diff --git a/data/web/admin.php b/data/web/admin.php index d8da73fe..4a72936c 100644 --- a/data/web/admin.php +++ b/data/web/admin.php @@ -124,7 +124,14 @@ if (!isset($_SESSION['gal']) && $license_cache = $redis->Get('LICENSE_STATUS_CAC
- + +
+
+
+
+
diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 6c7239c8..2c6131ac 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -1158,8 +1158,12 @@ function admin_api($action, $data = null) { case "edit": $regen_key = $data['admin_api_regen_key']; $active = (isset($data['active'])) ? 1 : 0; + $skip_ip_check = (isset($data['skip_ip_check'])) ? 1 : 0; $allow_from = array_map('trim', preg_split( "/( |,|;|\n)/", $data['allow_from'])); foreach ($allow_from as $key => $val) { + if (empty($val)) { + continue; + } if (!filter_var($val, FILTER_VALIDATE_IP)) { $_SESSION['return'][] = array( 'type' => 'warning', @@ -1171,7 +1175,7 @@ function admin_api($action, $data = null) { } } $allow_from = implode(',', array_unique(array_filter($allow_from))); - if (empty($allow_from)) { + if (empty($allow_from) && $skip_ip_check == 0) { $_SESSION['return'][] = array( 'type' => 'danger', 'log' => array(__FUNCTION__, $data), @@ -1189,20 +1193,31 @@ function admin_api($action, $data = null) { $stmt = $pdo->query("SELECT `api_key` FROM `api`"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); if (empty($num_results)) { - $stmt = $pdo->prepare("INSERT INTO `api` (`api_key`, `active`, `allow_from`) - VALUES (:api_key, :active, :allow_from);"); + $stmt = $pdo->prepare("INSERT INTO `api` (`api_key`, `skip_ip_check`, `active`, `allow_from`) + VALUES (:api_key, :skip_ip_check, :active, :allow_from);"); $stmt->execute(array( ':api_key' => $api_key, + ':skip_ip_check' => $skip_ip_check, ':active' => $active, ':allow_from' => $allow_from )); } else { - $stmt = $pdo->prepare("UPDATE `api` SET `active` = :active, `allow_from` = :allow_from ;"); - $stmt->execute(array( - ':active' => $active, - ':allow_from' => $allow_from - )); + if ($skip_ip_check == 0) { + $stmt = $pdo->prepare("UPDATE `api` SET `skip_ip_check` = :skip_ip_check, `active` = :active, `allow_from` = :allow_from ;"); + $stmt->execute(array( + ':active' => $active, + ':skip_ip_check' => $skip_ip_check, + ':allow_from' => $allow_from + )); + } + else { + $stmt = $pdo->prepare("UPDATE `api` SET `skip_ip_check` = :skip_ip_check, `active` = :active ;"); + $stmt->execute(array( + ':active' => $active, + ':skip_ip_check' => $skip_ip_check + )); + } } break; case "regen_key": diff --git a/data/web/inc/init_db.inc.php b/data/web/inc/init_db.inc.php index 1c3e5229..3efb7318 100644 --- a/data/web/inc/init_db.inc.php +++ b/data/web/inc/init_db.inc.php @@ -3,7 +3,7 @@ function init_db_schema() { try { global $pdo; - $db_version = "16022020_1304"; + $db_version = "16022020_1804"; $stmt = $pdo->query("SHOW TABLES LIKE 'versions'"); $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); @@ -170,6 +170,7 @@ function init_db_schema() { "cols" => array( "api_key" => "VARCHAR(255) NOT NULL", "allow_from" => "VARCHAR(512) NOT NULL", + "skip_ip_check" => "TINYINT(1) NOT NULL DEFAULT '0'", "created" => "DATETIME(0) NOT NULL DEFAULT NOW(0)", "modified" => "DATETIME ON UPDATE NOW(0)", "active" => "TINYINT(1) NOT NULL DEFAULT '1'" diff --git a/data/web/inc/sessions.inc.php b/data/web/inc/sessions.inc.php index bb9d3c81..e3840d2c 100644 --- a/data/web/inc/sessions.inc.php +++ b/data/web/inc/sessions.inc.php @@ -44,15 +44,16 @@ $_SESSION['LAST_ACTIVITY'] = time(); // API if (!empty($_SERVER['HTTP_X_API_KEY'])) { - $stmt = $pdo->prepare("SELECT `allow_from` FROM `api` WHERE `api_key` = :api_key AND `active` = '1';"); + $stmt = $pdo->prepare("SELECT * FROM `api` WHERE `api_key` = :api_key AND `active` = '1';"); $stmt->execute(array( ':api_key' => preg_replace('/[^a-zA-Z0-9-]/', '', $_SERVER['HTTP_X_API_KEY']) )); $api_return = $stmt->fetch(PDO::FETCH_ASSOC); - if (!empty($api_return['allow_from'])) { + if (!empty($api_return['api_key'])) { + $skip_ip_check = ($api_return['skip_ip_check'] == 1); $remote = get_remote_ip(false); $allow_from = array_map('trim', preg_split( "/( |,|;|\n)/", $api_return['allow_from'])); - if (in_array($remote, $allow_from)) { + if (in_array($remote, $allow_from) || $skip_ip_check === true) { $_SESSION['mailcow_cc_username'] = 'API'; $_SESSION['mailcow_cc_role'] = 'admin'; $_SESSION['mailcow_cc_api'] = true; diff --git a/data/web/js/site/admin.js b/data/web/js/site/admin.js index 8a3ece31..32f76888 100644 --- a/data/web/js/site/admin.js +++ b/data/web/js/site/admin.js @@ -359,6 +359,16 @@ jQuery(function($){ draw_oauth2_clients(); draw_transport_maps(); draw_queue(); + // API IP check toggle + $("#skip_ip_check").click(function( event ) { + $("#skip_ip_check").not(this).prop('checked', false); + if ($("#skip_ip_check:checked").length > 0) { + $('#allow_from').prop('disabled', true); + } + else { + $("#allow_from").removeAttr('disabled'); + } + }); // Relayhost $('#testRelayhostModal').on('show.bs.modal', function (e) { $('#test_relayhost_result').text("-"); diff --git a/data/web/js/site/mailbox.js b/data/web/js/site/mailbox.js index 11a7fce8..13a8398b 100644 --- a/data/web/js/site/mailbox.js +++ b/data/web/js/site/mailbox.js @@ -48,6 +48,13 @@ $(document).ready(function() { $(this.$domain).closest("select").selectpicker(); } }); + // todo + $('[data-page-size]').on('click', function(e){ + e.preventDefault(); + var newSize = $(this).data('page-size'); + var nextTable = $(this).nextAll('.table-responsive').find('table'); + FooTable.get(nextTable).pageSize(newSize); + }); // Clone mailbox mass actions $("div").find("[data-actions-header='true'").each(function() { $(this).html($(this).nextAll('.mass-actions-mailbox:first').html()); diff --git a/data/web/lang/lang.de.json b/data/web/lang/lang.de.json index 1f69cfae..60c45652 100644 --- a/data/web/lang/lang.de.json +++ b/data/web/lang/lang.de.json @@ -427,6 +427,7 @@ "nexthop": "Next Hop", "api_allow_from": "IP-Adressen für Zugriff", "api_key": "API-Key", + "api_skip_ip_check": "IP-Check für API nicht ausführen", "activate_api": "API aktivieren", "regen_api_key": "API-Key regenerieren", "ban_list_info": "Übersicht ausgesperrter Netzwerke: Netzwerk (verbleibende Banzeit) - [Aktionen].
IPs, die zum Entsperren eingereiht werden, verlassen die Liste aktiver Bans nach wenigen Sekunden.
Rote Labels sind Indikatoren für aktive Blacklisteinträge.", diff --git a/data/web/lang/lang.en.json b/data/web/lang/lang.en.json index 4db73e8c..789d5708 100644 --- a/data/web/lang/lang.en.json +++ b/data/web/lang/lang.en.json @@ -447,6 +447,7 @@ "relay_run": "Run test", "api_allow_from": "Allow API access from these IPs (separated by comma or new line)", "api_key": "API key", + "api_skip_ip_check": "Skip IP check for API", "activate_api": "Activate API", "regen_api_key": "Regenerate API key", "ban_list_info": "See a list of banned IPs below: network (remaining ban time) - [actions].
IPs queued to be unbanned will be removed from the active ban list within a few seconds.
Red labels indicate active permanent bans by blacklisting.",