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.",