From ce6bf18c2f5351897eae091e55c3583805a15ad8 Mon Sep 17 00:00:00 2001 From: andryyy Date: Fri, 26 May 2017 23:02:04 +0200 Subject: [PATCH] Web UI improvements --- data/web/add.php | 403 -------------- data/web/admin.php | 32 +- data/web/css/mailbox.css | 3 + data/web/css/user.css | 3 + data/web/edit.php | 24 +- data/web/inc/footer.inc.php | 2 +- data/web/inc/functions.dkim.inc.php | 151 ++++++ data/web/inc/functions.fwdhost.inc.php | 171 ++++++ data/web/inc/functions.inc.php | 305 ----------- data/web/inc/functions.mailbox.inc.php | 12 +- data/web/inc/functions.policy.inc.php | 8 +- data/web/inc/prerequisites.inc.php | 4 +- data/web/inc/triggers.inc.php | 40 -- data/web/inc/vars.inc.php | 8 +- data/web/js/add.js | 4 +- data/web/js/admin.js | 4 - data/web/js/api.js | 84 +-- data/web/js/mailbox.js | 24 + data/web/json_api.php | 493 ++++++++++++++++-- data/web/lang/lang.en.php | 6 +- data/web/mailbox.php | 27 +- .../{inc/tfa_modals.php => modals/footer.php} | 0 data/web/modals/mailbox.php | 303 +++++++++++ data/web/modals/user.php | 106 ++++ data/web/user.php | 19 +- 25 files changed, 1330 insertions(+), 906 deletions(-) delete mode 100644 data/web/add.php create mode 100644 data/web/inc/functions.dkim.inc.php create mode 100644 data/web/inc/functions.fwdhost.inc.php rename data/web/{inc/tfa_modals.php => modals/footer.php} (100%) create mode 100644 data/web/modals/mailbox.php create mode 100644 data/web/modals/user.php diff --git a/data/web/add.php b/data/web/add.php deleted file mode 100644 index b81a4e55..00000000 --- a/data/web/add.php +++ /dev/null @@ -1,403 +0,0 @@ - -
-
-
-
-
-

-
-
- -

-
"> - - - -
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
-
- -
- -

-
-
-
-
-
-
- -
-
-
-
-
- -
-
-

-
- -

-

-
"> - -
- -
- -

-
-
-
- -
- -

-
-
-
-
-
- -
-
-
-
-
- -
-
-
- -

-
"> - -
- -
- -

-
-
-
- -
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
- -

-
"> - -
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
-
- -
-
-
-
-
- -
-
-
- -

-
"> - - -
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
-
- - - -

-

-
"> - - - -
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
- -
- -
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
-
- -
-
-
-
-
- -
-
-
- - - -
-
-
-
- -
- - diff --git a/data/web/admin.php b/data/web/admin.php index 64ad77ec..674d7f29 100644 --- a/data/web/admin.php +++ b/data/web/admin.php @@ -176,7 +176,7 @@ $tfa_data = get_tfa();
@@ -204,8 +204,8 @@ $tfa_data = get_tfa();
@@ -235,8 +235,8 @@ $tfa_data = get_tfa(); } } } - foreach(dkim_get_blind_keys() as $blind) { - if (!empty($dkim = dkim_get_key_details($blind))) { + foreach(dkim('blind') as $blind) { + if (!empty($dkim = dkim('details', $blind))) { ?>
@@ -257,7 +257,7 @@ $tfa_data = get_tfa(); ?> -
+
@@ -272,7 +272,7 @@ $tfa_data = get_tfa();
- +
@@ -281,18 +281,24 @@ $tfa_data = get_tfa();

+
+
+
-
-
-

-
+
@@ -303,7 +309,7 @@ $tfa_data = get_tfa();
- +
diff --git a/data/web/css/mailbox.css b/data/web/css/mailbox.css index 79e88255..63e688dc 100644 --- a/data/web/css/mailbox.css +++ b/data/web/css/mailbox.css @@ -27,3 +27,6 @@ table.footable>tbody>tr.footable-empty>td { user-select: none; padding:10px 0 10px 10px; } +.inputMissingAttr { + border-color: #FF4136; +} \ No newline at end of file diff --git a/data/web/css/user.css b/data/web/css/user.css index 605a1010..2222b624 100644 --- a/data/web/css/user.css +++ b/data/web/css/user.css @@ -22,3 +22,6 @@ table.footable>tbody>tr.footable-empty>td { user-select: none; padding:10px 0 10px 0; } +.inputMissingAttr { + border-color: #FF4136; +} diff --git a/data/web/edit.php b/data/web/edit.php index d9121401..d4f6ce19 100644 --- a/data/web/edit.php +++ b/data/web/edit.php @@ -208,12 +208,12 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
-

Domain: (dkim._domainkey)

+

Domain: (._domainkey)

@@ -233,17 +233,15 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
- +
-
+
- - - +
@@ -257,17 +255,15 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
- +
-
+
- - - +
@@ -312,12 +308,12 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm

-

Domain: (dkim._domainkey)

+

Domain: (._domainkey)

diff --git a/data/web/inc/footer.inc.php b/data/web/inc/footer.inc.php index d364a4df..336a9c4f 100644 --- a/data/web/inc/footer.inc.php +++ b/data/web/inc/footer.inc.php @@ -1,5 +1,5 @@ diff --git a/data/web/inc/functions.dkim.inc.php b/data/web/inc/functions.dkim.inc.php new file mode 100644 index 00000000..16fb4da1 --- /dev/null +++ b/data/web/inc/functions.dkim.inc.php @@ -0,0 +1,151 @@ + 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + $key_length = intval($_data['key_size']); + $dkim_selector = (isset($_data['dkim_selector'])) ? $_data['dkim_selector'] : 'dkim'; + $domain = $_data['domain']; + if (!is_valid_domain_name($domain) || !is_numeric($key_length)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid']) + ); + return false; + } + if ($redis->hGet('DKIM_PUB_KEYS', $domain)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid']) + ); + return false; + } + if (!ctype_alnum($dkim_selector)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid']) + ); + return false; + } + $config = array( + "digest_alg" => "sha256", + "private_key_bits" => $key_length, + "private_key_type" => OPENSSL_KEYTYPE_RSA, + ); + if ($keypair_ressource = openssl_pkey_new($config)) { + $key_details = openssl_pkey_get_details($keypair_ressource); + $pubKey = implode(array_slice( + array_filter( + explode(PHP_EOL, $key_details['key']) + ), 1, -1) + ); + // Save public key and selector to redis + try { + $redis->hSet('DKIM_PUB_KEYS', $domain, $pubKey); + $redis->hSet('DKIM_SELECTORS', $domain, $dkim_selector); + } + catch (RedisException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'Redis: '.$e + ); + return false; + } + // Export private key and save private key to redis + openssl_pkey_export($keypair_ressource, $privKey); + if (isset($privKey) && !empty($privKey)) { + try { + $redis->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, trim($privKey)); + } + catch (RedisException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'Redis: '.$e + ); + return false; + } + } + $_SESSION['return'] = array( + 'type' => 'success', + 'msg' => sprintf($lang['success']['dkim_added']) + ); + return true; + } + else { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid']) + ); + return false; + } + break; + case 'details': + if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $_data)) { + return false; + } + $dkimdata = array(); + if ($redis_dkim_key_data = $redis->hGet('DKIM_PUB_KEYS', $_data)) { + $dkimdata['pubkey'] = $redis_dkim_key_data; + $dkimdata['length'] = (strlen($dkimdata['pubkey']) < 391) ? 1024 : 2048; + $dkimdata['dkim_txt'] = 'v=DKIM1;k=rsa;t=s;s=email;p=' . $redis_dkim_key_data; + $dkimdata['dkim_selector'] = $redis->hGet('DKIM_SELECTORS', $_data); + } + return $dkimdata; + break; + case 'blind': + if ($_SESSION['mailcow_cc_role'] != "admin") { + return false; + } + $blinddkim = array(); + foreach ($redis->hKeys('DKIM_PUB_KEYS') as $redis_dkim_domain) { + $blinddkim[] = $redis_dkim_domain; + } + return array_diff($blinddkim, array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains'))); + break; + case 'delete': + $domains = (array)$_data['domains']; + if ($_SESSION['mailcow_cc_role'] != "admin") { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + foreach ($domains as $domain) { + if (!is_valid_domain_name($domain)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid']) + ); + return false; + } + try { + $selector = $redis->hGet('DKIM_SELECTORS', $domain); + $redis->hDel('DKIM_PUB_KEYS', $domain); + $redis->hDel('DKIM_PRIV_KEYS', $selector . '.' . $domain); + $redis->hDel('DKIM_SELECTORS', $domain); + } + catch (RedisException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'Redis: '.$e + ); + return false; + } + } + $_SESSION['return'] = array( + 'type' => 'success', + 'msg' => sprintf($lang['success']['dkim_removed'], htmlspecialchars(implode(', ', $domains))) + ); + break; + } +} \ No newline at end of file diff --git a/data/web/inc/functions.fwdhost.inc.php b/data/web/inc/functions.fwdhost.inc.php new file mode 100644 index 00000000..6f3e8022 --- /dev/null +++ b/data/web/inc/functions.fwdhost.inc.php @@ -0,0 +1,171 @@ + 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + $source = $_data['hostname']; + $host = trim($_data['hostname']); + $filter_spam = (isset($_data['filter_spam']) && $_data['filter_spam'] == 1) ? 1 : 0; + if (preg_match('/^[0-9a-fA-F:\/]+$/', $host)) { // IPv6 address + $hosts = array($host); + } + elseif (preg_match('/^[0-9\.\/]+$/', $host)) { // IPv4 address + $hosts = array($host); + } + else { + $hosts = get_outgoing_hosts_best_guess($host); + } + if (empty($hosts)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'Invalid host specified: '. htmlspecialchars($host) + ); + return false; + } + foreach ($hosts as $host) { + try { + $redis->hSet('WHITELISTED_FWD_HOST', $host, $source); + if ($filter_spam == 0) { + $redis->hSet('KEEP_SPAM', $host, 1); + } + elseif ($redis->hGet('KEEP_SPAM', $host)) { + $redis->hDel('KEEP_SPAM', $host); + } + } + catch (RedisException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'Redis: '.$e + ); + return false; + } + } + $_SESSION['return'] = array( + 'type' => 'success', + 'msg' => sprintf($lang['success']['forwarding_host_added'], htmlspecialchars(implode(', ', $hosts))) + ); + break; + case 'edit': + global $lang; + if ($_SESSION['mailcow_cc_role'] != "admin") { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + $fwdhosts = (array)$_data['fwdhost']; + foreach ($fwdhosts as $fwdhost) { + $is_now = fwdhost('details', $fwdhost); + if (!empty($is_now)) { + $keep_spam = (isset($_data['keep_spam'])) ? $_data['keep_spam'] : $is_now['keep_spam']; + } + else { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + try { + if ($keep_spam == 1) { + $redis->hSet('KEEP_SPAM', $fwdhost, 1); + } + else { + $redis->hDel('KEEP_SPAM', $fwdhost); + } + } + catch (RedisException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'Redis: '.$e + ); + return false; + } + } + $_SESSION['return'] = array( + 'type' => 'success', + 'msg' => sprintf($lang['success']['object_modified'], htmlspecialchars(implode(', ', $fwdhosts))) + ); + break; + case 'delete': + $hosts = (array)$_data['forwardinghost']; + foreach ($hosts as $host) { + try { + $redis->hDel('WHITELISTED_FWD_HOST', $host); + $redis->hDel('KEEP_SPAM', $host); + } + catch (RedisException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'Redis: '.$e + ); + return false; + } + } + $_SESSION['return'] = array( + 'type' => 'success', + 'msg' => sprintf($lang['success']['forwarding_host_removed'], htmlspecialchars(implode(', ', $hosts))) + ); + break; + case 'get': + if ($_SESSION['mailcow_cc_role'] != "admin") { + return false; + } + $fwdhostsdata = array(); + try { + $fwd_hosts = $redis->hGetAll('WHITELISTED_FWD_HOST'); + if (!empty($fwd_hosts)) { + foreach ($fwd_hosts as $fwd_host => $source) { + $keep_spam = ($redis->hGet('KEEP_SPAM', $fwd_host)) ? "yes" : "no"; + $fwdhostsdata[] = array( + 'host' => $fwd_host, + 'source' => $source, + 'keep_spam' => $keep_spam + ); + } + } + } + catch (RedisException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'Redis: '.$e + ); + return false; + } + return $fwdhostsdata; + break; + case 'details': + $fwdhostdetails = array(); + if (!isset($_data) || empty($_data)) { + return false; + } + try { + if ($source = $redis->hGet('WHITELISTED_FWD_HOST', $_data)) { + $fwdhostdetails['host'] = $_data; + $fwdhostdetails['source'] = $source; + $fwdhostdetails['keep_spam'] = ($redis->hGet('KEEP_SPAM', $_data)) ? "yes" : "no"; + } + } + catch (RedisException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'Redis: '.$e + ); + return false; + } + return $fwdhostdetails; + break; + } +} \ No newline at end of file diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index f6fe886a..9ddfb726 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -1310,317 +1310,12 @@ function get_admin_details() { } return $data; } -function dkim_add_key($postarray) { - global $lang; - global $pdo; - global $redis; - if ($_SESSION['mailcow_cc_role'] != "admin") { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => sprintf($lang['danger']['access_denied']) - ); - return false; - } - // if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) { - // $_SESSION['return'] = array( - // 'type' => 'danger', - // 'msg' => sprintf($lang['danger']['access_denied']) - // ); - // return false; - // } - $key_length = intval($postarray['key_size']); - $dkim_selector = (isset($postarray['dkim_selector'])) ? $postarray['dkim_selector'] : 'dkim'; - $domain = $postarray['domain']; - if (!is_valid_domain_name($domain) || !is_numeric($key_length)) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid']) - ); - return false; - } - - if (!empty(glob($GLOBALS['MC_DKIM_TXTS'] . '/' . $domain . '.dkim')) || - $redis->hGet('DKIM_PUB_KEYS', $domain)) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid']) - ); - return false; - } - - if (!ctype_alnum($dkim_selector)) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid']) - ); - return false; - } - - $config = array( - "digest_alg" => "sha256", - "private_key_bits" => $key_length, - "private_key_type" => OPENSSL_KEYTYPE_RSA, - ); - if ($keypair_ressource = openssl_pkey_new($config)) { - $key_details = openssl_pkey_get_details($keypair_ressource); - $pubKey = implode(array_slice( - array_filter( - explode(PHP_EOL, $key_details['key']) - ), 1, -1) - ); - // Save public key and selector to redis - try { - $redis->hSet('DKIM_PUB_KEYS', $domain, $pubKey); - $redis->hSet('DKIM_SELECTORS', $domain, $dkim_selector); - } - catch (RedisException $e) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => 'Redis: '.$e - ); - return false; - } - // Export private key and save private key to redis - openssl_pkey_export($keypair_ressource, $privKey); - if (isset($privKey) && !empty($privKey)) { - try { - $redis->hSet('DKIM_PRIV_KEYS', $dkim_selector . '.' . $domain, trim($privKey)); - } - catch (RedisException $e) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => 'Redis: '.$e - ); - return false; - } - } - $_SESSION['return'] = array( - 'type' => 'success', - 'msg' => sprintf($lang['success']['dkim_added']) - ); - return true; - } - else { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid']) - ); - return false; - } -} -function dkim_get_key_details($domain) { - global $redis; - if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) { - return false; - } - $data = array(); - if ($redis_dkim_key_data = $redis->hGet('DKIM_PUB_KEYS', $domain)) { - $data['pubkey'] = $redis_dkim_key_data; - $data['length'] = (strlen($data['pubkey']) < 391) ? 1024 : 2048; - $data['dkim_txt'] = 'v=DKIM1;k=rsa;t=s;s=email;p=' . $redis_dkim_key_data; - $data['dkim_selector'] = $redis->hGet('DKIM_SELECTORS', $domain); - } - return $data; -} -function dkim_get_blind_keys() { - global $redis; - global $lang; - if ($_SESSION['mailcow_cc_role'] != "admin") { - return false; - } - $domains = array(); - foreach ($redis->hKeys('DKIM_PUB_KEYS') as $redis_dkim_domain) { - $domains[] = $redis_dkim_domain; - } - return array_diff($domains, array_merge(mailbox('get', 'domains'), mailbox('get', 'alias_domains'))); -} -function dkim_delete_key($postarray) { - global $redis; - global $lang; - if (!is_array($postarray['domains'])) { - $domains = array(); - $domains[] = $postarray['domains']; - } - else { - $domains = $postarray['domains']; - } - if ($_SESSION['mailcow_cc_role'] != "admin") { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => sprintf($lang['danger']['access_denied']) - ); - return false; - } - foreach ($domains as $domain) { - if (!is_valid_domain_name($domain)) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => sprintf($lang['danger']['dkim_domain_or_sel_invalid']) - ); - return false; - } - try { - $selector = $redis->hGet('DKIM_SELECTORS', $domain); - $redis->hDel('DKIM_PUB_KEYS', $domain); - $redis->hDel('DKIM_PRIV_KEYS', $selector . '.' . $domain); - $redis->hDel('DKIM_SELECTORS', $domain); - } - catch (RedisException $e) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => 'Redis: '.$e - ); - return false; - } - } - $_SESSION['return'] = array( - 'type' => 'success', - 'msg' => sprintf($lang['success']['dkim_removed'], htmlspecialchars(implode(', ', $domains))) - ); - return true; -} function get_u2f_registrations($username) { global $pdo; $sel = $pdo->prepare("SELECT * FROM `tfa` WHERE `authmech` = 'u2f' AND `username` = ? AND `active` = '1'"); $sel->execute(array($username)); return $sel->fetchAll(PDO::FETCH_OBJ); } -function get_forwarding_hosts() { - global $redis; - $data = array(); - try { - $fwd_hosts = $redis->hGetAll('WHITELISTED_FWD_HOST'); - if (!empty($fwd_hosts)) { - foreach ($fwd_hosts as $fwd_host => $source) { - $data[] = $fwd_host; - } - } - } - catch (RedisException $e) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => 'Redis: '.$e - ); - return false; - } - return $data; -} -function get_forwarding_host_details($host) { - global $redis; - $data = array(); - if (!isset($host) || empty($host)) { - return false; - } - try { - if ($source = $redis->hGet('WHITELISTED_FWD_HOST', $host)) { - $data['host'] = $host; - $data['source'] = $source; - $data['keep_spam'] = ($redis->hGet('KEEP_SPAM', $host)) ? "yes" : "no"; - } - } - catch (RedisException $e) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => 'Redis: '.$e - ); - return false; - } - return $data; -} -function add_forwarding_host($postarray) { - require_once 'spf.inc.php'; - global $redis; - global $lang; - if ($_SESSION['mailcow_cc_role'] != "admin") { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => sprintf($lang['danger']['access_denied']) - ); - return false; - } - $source = $postarray['hostname']; - $host = trim($postarray['hostname']); - $filter_spam = $postarray['filter_spam']; - if (isset($postarray['filter_spam']) && $postarray['filter_spam'] == 1) { - $filter_spam = 1; - } - else { - $filter_spam = 0; - } - if (preg_match('/^[0-9a-fA-F:\/]+$/', $host)) { // IPv6 address - $hosts = array($host); - } - elseif (preg_match('/^[0-9\.\/]+$/', $host)) { // IPv4 address - $hosts = array($host); - } - else { - $hosts = get_outgoing_hosts_best_guess($host); - } - if (empty($hosts)) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => 'Invalid host specified: '. htmlspecialchars($host) - ); - return false; - } - foreach ($hosts as $host) { - try { - $redis->hSet('WHITELISTED_FWD_HOST', $host, $source); - if ($filter_spam == 0) { - $redis->hSet('KEEP_SPAM', $host, 1); - } - elseif ($redis->hGet('KEEP_SPAM', $host)) { - $redis->hDel('KEEP_SPAM', $host); - } - } - catch (RedisException $e) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => 'Redis: '.$e - ); - return false; - } - } - $_SESSION['return'] = array( - 'type' => 'success', - 'msg' => sprintf($lang['success']['forwarding_host_added'], htmlspecialchars(implode(', ', $hosts))) - ); -} -function delete_forwarding_host($postarray) { - global $redis; - global $lang; - if ($_SESSION['mailcow_cc_role'] != "admin") { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => sprintf($lang['danger']['access_denied']) - ); - return false; - } - if (!is_array($postarray['forwardinghost'])) { - $hosts = array(); - $hosts[] = $postarray['forwardinghost']; - } - else { - $hosts = $postarray['forwardinghost']; - } - foreach ($hosts as $host) { - try { - $redis->hDel('WHITELISTED_FWD_HOST', $host); - $redis->hDel('KEEP_SPAM', $host); - } - catch (RedisException $e) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => 'Redis: '.$e - ); - return false; - } - } - $_SESSION['return'] = array( - 'type' => 'success', - 'msg' => sprintf($lang['success']['forwarding_host_removed'], htmlspecialchars(implode(', ', $hosts))) - ); -} function get_logs($container, $lines = 100) { global $lang; global $redis; diff --git a/data/web/inc/functions.mailbox.inc.php b/data/web/inc/functions.mailbox.inc.php index 53a93c53..900fa560 100644 --- a/data/web/inc/functions.mailbox.inc.php +++ b/data/web/inc/functions.mailbox.inc.php @@ -648,7 +648,7 @@ function mailbox($_action, $_type, $_data = null) { if ($num_results == 0) { $_SESSION['return'] = array( 'type' => 'danger', - 'msg' => sprintf($lang['danger']['domain_not_found'], $domain) + 'msg' => sprintf($lang['danger']['domain_not_found'], htmlspecialchars($domain)) ); return false; } @@ -832,7 +832,7 @@ function mailbox($_action, $_type, $_data = null) { if ($num_results == 0) { $_SESSION['return'] = array( 'type' => 'danger', - 'msg' => sprintf($lang['danger']['domain_not_found'], $domain) + 'msg' => sprintf($lang['danger']['domain_not_found'], htmlspecialchars($domain)) ); return false; } @@ -875,13 +875,7 @@ function mailbox($_action, $_type, $_data = null) { case 'edit': switch ($_type) { case 'alias_domain': - if (!is_array($_data['alias_domain'])) { - $alias_domains = array(); - $alias_domains[] = $_data['alias_domain']; - } - else { - $alias_domains = $_data['alias_domain']; - } + $alias_domains = (array)$_data['alias_domain']; foreach ($alias_domains as $alias_domain) { $alias_domain = idn_to_ascii(strtolower(trim($alias_domain))); $is_now = mailbox('get', 'alias_domain_details', $alias_domain); diff --git a/data/web/inc/functions.policy.inc.php b/data/web/inc/functions.policy.inc.php index 01ef13ab..3070b5dc 100644 --- a/data/web/inc/functions.policy.inc.php +++ b/data/web/inc/functions.policy.inc.php @@ -168,13 +168,7 @@ function policy($_action, $_scope, $_data = null) { case 'delete': switch ($_scope) { case 'domain': - if (!is_array($_data['prefid'])) { - $prefids = array(); - $prefids[] = $_data['prefid']; - } - else { - $prefids = $_data['prefid']; - } + (array)$prefids = $_data['prefid']; foreach ($prefids as $prefid) { if (!is_numeric($prefid)) { $_SESSION['return'] = array( diff --git a/data/web/inc/prerequisites.inc.php b/data/web/inc/prerequisites.inc.php index 867bc106..f1091d92 100644 --- a/data/web/inc/prerequisites.inc.php +++ b/data/web/inc/prerequisites.inc.php @@ -14,7 +14,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/lib/vendor/autoload.php'; // U2F API + T/HOTP API $u2f = new u2flib_server\U2F('https://' . $_SERVER['HTTP_HOST']); -$tfa = new RobThree\Auth\TwoFactorAuth('mailcow UI'); +$tfa = new RobThree\Auth\TwoFactorAuth($OTP_LABEL); // Redis $redis = new Redis(); @@ -60,6 +60,8 @@ include $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.'.$_SESSION['mailcow_locale'].'. require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.mailbox.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.policy.inc.php'; +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.dkim.inc.php'; +require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.fwdhost.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/init_db.inc.php'; require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/triggers.inc.php'; init_db_schema(); diff --git a/data/web/inc/triggers.inc.php b/data/web/inc/triggers.inc.php index 1fcaf256..4fd207cf 100644 --- a/data/web/inc/triggers.inc.php +++ b/data/web/inc/triggers.inc.php @@ -53,33 +53,11 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admi } } } - - if (isset($_POST["edit_admin_account"])) { - edit_admin_account($_POST); - } - if (isset($_POST["dkim_delete_key"])) { - dkim_delete_key($_POST); - } - if (isset($_POST["dkim_add_key"])) { - dkim_add_key($_POST); - } - if (isset($_POST["add_forwarding_host"])) { - add_forwarding_host($_POST); - } - if (isset($_POST["delete_forwarding_host"])) { - delete_forwarding_host($_POST); - } } if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "user") { if (isset($_POST["edit_user_account"])) { edit_user_account($_POST); } - if (isset($_POST["add_policy_list_item"])) { - policy('add', 'mailbox', $_POST); - } - if (isset($_POST["add_syncjob"])) { - mailbox('add', 'syncjob', $_POST); - } if (isset($_POST["edit_syncjob"])) { mailbox('edit', 'syncjob', $_POST); } @@ -94,24 +72,6 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm if (isset($_POST["unset_tfa_key"])) { unset_tfa_key($_POST); } - if (isset($_POST["add_policy_list_item"])) { - policy('add', 'domain', $_POST); - } - if (isset($_POST["mailbox_add_domain"])) { - mailbox('add', 'domain', $_POST); - } - if (isset($_POST["mailbox_add_alias"])) { - mailbox('add', 'alias', $_POST); - } - if (isset($_POST["mailbox_add_alias_domain"])) { - mailbox('add', 'alias_domain', $_POST); - } - if (isset($_POST["mailbox_add_mailbox"])) { - mailbox('add', 'mailbox', $_POST); - } - if (isset($_POST["mailbox_add_resource"])) { - mailbox('add', 'resource', $_POST); - } if (isset($_POST["mailbox_edit_alias"])) { mailbox('edit', 'alias', $_POST); } diff --git a/data/web/inc/vars.inc.php b/data/web/inc/vars.inc.php index d5845a46..a29f742c 100644 --- a/data/web/inc/vars.inc.php +++ b/data/web/inc/vars.inc.php @@ -1,7 +1,6 @@ ' + - ' ' + lang.remove + '' + - '
'; if (item.keep_spam == "yes") { item.keep_spam = lang.no; } diff --git a/data/web/js/api.js b/data/web/js/api.js index f1f760be..ef926476 100644 --- a/data/web/js/api.js +++ b/data/web/js/api.js @@ -44,7 +44,6 @@ $(document).ready(function() { $(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(); }); @@ -71,15 +70,18 @@ $(document).ready(function() { } if (typeof multi_data[id] == "undefined") return; api_items = multi_data[id]; - if (Object.keys(api_items).length !== 0) { $.ajax({ type: "POST", dataType: "json", - data: { "items": JSON.stringify(api_items), "attr": JSON.stringify(api_attr), "csrf_token": csrf_token }, + data: { + "items": JSON.stringify(api_items), + "attr": JSON.stringify(api_attr), + "csrf_token": csrf_token + }, url: '/api/v1/' + api_url, jsonp: false, - complete: function (data) { + complete: function(data) { // var reponse = (JSON.parse(data.responseText)); // console.log(reponse.type); // console.log(reponse.msg); @@ -98,16 +100,34 @@ $(document).ready(function() { // If clicked button is in a form with the same data-id as the button, // we merge all input fields by {"name":"value"} into api-attr if ($(this).closest("form").data('id') == id) { - var attr_to_merge = $(this).closest("form").serializeObject(); - var api_attr = $.extend(api_attr, attr_to_merge) + var req_empty = false; + $(this).closest("form").find('select, textarea, input').each(function() { + if ($(this).prop('required')) { + if (!$(this).val()) { + req_empty = true; + $(this).addClass('inputMissingAttr'); + } else { + $(this).removeClass('inputMissingAttr'); + } + } + }); + if (!req_empty) { + var attr_to_merge = $(this).closest("form").serializeObject(); + var api_attr = $.extend(api_attr, attr_to_merge) + } else { + return false; + } } $.ajax({ type: "POST", dataType: "json", - data: { "attr": JSON.stringify(api_attr), "csrf_token": csrf_token }, + data: { + "attr": JSON.stringify(api_attr), + "csrf_token": csrf_token + }, url: '/api/v1/' + api_url, jsonp: false, - complete: function (data) { + complete: function(data) { // var reponse = (JSON.parse(data.responseText)); // console.log(reponse.type); // console.log(reponse.msg); @@ -115,6 +135,7 @@ $(document).ready(function() { } }); }); + // General API delete actions $(document).on('click', '#delete_selected', function(e) { e.preventDefault(); @@ -125,7 +146,7 @@ $(document).ready(function() { if (typeof multi_data[id] == "undefined") { multi_data[id] = []; } - multi_data[id].splice($.inArray($(this).data('item'), multi_data[id]),1); + multi_data[id].splice($.inArray($(this).data('item'), multi_data[id]), 1); multi_data[id].push($(this).data('item')); } if (typeof $(this).data('text') !== 'undefined') { @@ -135,33 +156,36 @@ $(document).ready(function() { 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 () { + $(document).on('show.bs.modal', '#ConfirmDeleteModal', function() { $("#ItemsToDelete").empty(); for (var i in data_array) { $("#ItemsToDelete").append("
  • " + data_array[i] + "
  • "); } }) $('#ConfirmDeleteModal').modal({ - backdrop: 'static', - keyboard: false - }) - .one('click', '#IsConfirmed', function(e) { - $.ajax({ - type: "POST", - dataType: "json", - cache: false, - data: { "items": JSON.stringify(data_array), "csrf_token": csrf_token }, - url: '/api/v1/' + api_url, - jsonp: false, - complete: function (data) { - window.location = window.location.href.split("#")[0]; - } + backdrop: 'static', + keyboard: false + }) + .one('click', '#IsConfirmed', function(e) { + $.ajax({ + type: "POST", + dataType: "json", + cache: false, + data: { + "items": JSON.stringify(data_array), + "csrf_token": csrf_token + }, + url: '/api/v1/' + api_url, + jsonp: false, + complete: function(data) { + window.location = window.location.href.split("#")[0]; + } + }); + }) + .one('click', '#isCanceled', function(e) { + // Remove event handler to allow to close modal and restart dialog without multiple submits + $('#ConfirmDeleteModal').off(); + $('#ConfirmDeleteModal').modal('hide'); }); - }) - .one('click', '#isCanceled', function(e) { - // Remove event handler to allow to close modal and restart dialog without multiple submits - $('#ConfirmDeleteModal').off(); - $('#ConfirmDeleteModal').modal('hide'); - }); }); }); \ No newline at end of file diff --git a/data/web/js/mailbox.js b/data/web/js/mailbox.js index 80d84339..1171d8cb 100644 --- a/data/web/js/mailbox.js +++ b/data/web/js/mailbox.js @@ -1,3 +1,27 @@ +$(document).ready(function() { + // Auto-fill domain quota when adding new domain + auto_fill_quota = function(domain) { + $.get("/api/v1/get/domain/" + domain, function(data){ + var result = $.parseJSON(JSON.stringify(data)); + max_new_mailbox_quota = ( result.max_new_mailbox_quota / 1048576); + if (max_new_mailbox_quota != '0') { + $("#quotaBadge").html('max. ' + max_new_mailbox_quota + ' MiB'); + $('#addInputQuota').attr({"disabled": false, "value": "", "type": "number", "max": max_new_mailbox_quota}); + $('#addInputQuota').val(max_new_mailbox_quota); + } + else { + $("#quotaBadge").html('max. ' + max_new_mailbox_quota + ' MiB'); + $('#addInputQuota').attr({"disabled": true, "value": "", "type": "text", "value": "n/a"}); + $('#addInputQuota').val(max_new_mailbox_quota); + } + }); + } + $('#addSelectDomain').on('change', function() { + auto_fill_quota($('#addSelectDomain').val()); + }); + auto_fill_quota($('#addSelectDomain').val()); +}); + jQuery(function($){ // Calculation human readable file sizes function humanFileSize(bytes) { diff --git a/data/web/json_api.php b/data/web/json_api.php index 70e42a35..96d6f2e1 100644 --- a/data/web/json_api.php +++ b/data/web/json_api.php @@ -60,6 +60,336 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u )); } break; + case "mailbox": + if (isset($_POST['attr'])) { + $attr = (array)json_decode($_POST['attr'], true); + if (mailbox('add', 'mailbox', $attr) === false) { + if (isset($_SESSION['return'])) { + echo json_encode($_SESSION['return']); + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot add item' + )); + } + } + 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 attributes in post data' + )); + } + break; + case "domain": + if (isset($_POST['attr'])) { + $attr = (array)json_decode($_POST['attr'], true); + if (mailbox('add', 'domain', $attr) === false) { + if (isset($_SESSION['return'])) { + echo json_encode($_SESSION['return']); + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot add item' + )); + } + } + 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 attributes in post data' + )); + } + break; + case "resource": + if (isset($_POST['attr'])) { + $attr = (array)json_decode($_POST['attr'], true); + if (mailbox('add', 'resource', $attr) === false) { + if (isset($_SESSION['return'])) { + echo json_encode($_SESSION['return']); + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot add item' + )); + } + } + 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 attributes in post data' + )); + } + break; + case "alias": + if (isset($_POST['attr'])) { + $attr = (array)json_decode($_POST['attr'], true); + if (mailbox('add', 'alias', $attr) === false) { + if (isset($_SESSION['return'])) { + echo json_encode($_SESSION['return']); + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot add item' + )); + } + } + 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 attributes in post data' + )); + } + break; + case "syncjob": + if (isset($_POST['attr'])) { + $attr = (array)json_decode($_POST['attr'], true); + if (mailbox('add', 'syncjob', $attr) === false) { + if (isset($_SESSION['return'])) { + echo json_encode($_SESSION['return']); + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot add item' + )); + } + } + 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 attributes in post data' + )); + } + break; + case "domain-policy": + if (isset($_POST['attr'])) { + $attr = (array)json_decode($_POST['attr'], true); + if (policy('add', 'domain', $attr) === false) { + if (isset($_SESSION['return'])) { + echo json_encode($_SESSION['return']); + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot add item' + )); + } + } + 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 attributes in post data' + )); + } + break; + case "mailbox-policy": + if (isset($_POST['attr'])) { + $attr = (array)json_decode($_POST['attr'], true); + if (policy('add', 'mailbox', $attr) === false) { + if (isset($_SESSION['return'])) { + echo json_encode($_SESSION['return']); + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot add item' + )); + } + } + 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 attributes in post data' + )); + } + break; + case "alias-domain": + if (isset($_POST['attr'])) { + $attr = (array)json_decode($_POST['attr'], true); + if (mailbox('add', 'alias_domain', $attr) === false) { + if (isset($_SESSION['return'])) { + echo json_encode($_SESSION['return']); + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot add item' + )); + } + } + 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 attributes in post data' + )); + } + break; + case "fwdhost": + if (isset($_POST['attr'])) { + $attr = (array)json_decode($_POST['attr'], true); + if (fwdhost('add', $attr) === false) { + if (isset($_SESSION['return'])) { + echo json_encode($_SESSION['return']); + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot add item' + )); + } + } + 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 attributes in post data' + )); + } + break; + case "dkim": + if (isset($_POST['attr'])) { + $attr = (array)json_decode($_POST['attr'], true); + if (dkim('add', $attr) === false) { + if (isset($_SESSION['return'])) { + echo json_encode($_SESSION['return']); + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot add item' + )); + } + } + 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 attributes in post data' + )); + } + break; case "domain_admin": if (isset($_POST['attr'])) { $attr = (array)json_decode($_POST['attr'], true); @@ -353,10 +683,32 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u case "fwdhost": switch ($object) { case "all": - $fwdhosts = get_forwarding_hosts(); - if (!empty($fwdhosts)) { - foreach ($fwdhosts as $fwdhost) { - if ($details = get_forwarding_host_details($fwdhost)) { + $data = fwdhost('get'); + if (!isset($data) || empty($data)) { + echo '{}'; + } + else { + echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); + } + break; + default: + $data = fwdhost('details', $object); + if (!isset($data) || empty($data)) { + echo '{}'; + } + else { + echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); + } + break; + } + break; + case "alias-domain": + switch ($object) { + case "all": + $alias_domains = mailbox('get', 'alias_domains'); + if (!empty($alias_domains)) { + foreach ($alias_domains as $alias_domain) { + if ($details = mailbox('get', 'alias_domain_details', $alias_domain)) { $data[] = $details; } else { @@ -372,47 +724,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u } break; default: - $data = get_forwarding_host_details($object); - if (!isset($data) || empty($data)) { - echo '{}'; - } - else { - echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); - } - break; - } - break; - case "alias-domain": - switch ($object) { - case "all": - $domains = mailbox('get', 'domains'); - if (!empty($domains)) { - foreach ($domains as $domain) { - $alias_domains = mailbox('get', 'alias_domains', $domain); - if (!empty($alias_domains)) { - foreach ($alias_domains as $alias_domain) { - if ($details = mailbox('get', 'alias_domain_details', $alias_domain)) { - $data[] = $details; - } - else { - continue; - } - } - } - } - if (!isset($data) || empty($data)) { - echo '{}'; - } - else { - echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT); - } - } - else { - echo '{}'; - } - break; - default: - $data = mailbox('get', 'alias_domains', $object); + $data = mailbox('get', 'alias_domain_details', $object); if (!isset($data) || empty($data)) { echo '{}'; } @@ -615,7 +927,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u if (isset($_POST['items'])) { $items = (array)json_decode($_POST['items'], true); if (is_array($items)) { - if (delete_forwarding_host(array('forwardinghost' => $items)) === false) { + if (fwdhost('delete', array('forwardinghost' => $items)) === false) { if (isset($_SESSION['return'])) { echo json_encode($_SESSION['return']); } @@ -656,7 +968,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u if (isset($_POST['items'])) { $items = (array)json_decode($_POST['items'], true); if (is_array($items)) { - if (dkim_delete_key(array('domains' => $items)) === false) { + if (dkim('delete', array('domains' => $items)) === false) { if (isset($_SESSION['return'])) { echo json_encode($_SESSION['return']); } @@ -857,7 +1169,7 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u )); } break; - case "policy_mailbox": + case "mailbox-policy": if (isset($_POST['items'])) { $items = (array)json_decode($_POST['items'], true); if (is_array($items)) { @@ -898,6 +1210,47 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u )); } break; + case "domain-policy": + if (isset($_POST['items'])) { + $items = (array)json_decode($_POST['items'], true); + if (is_array($items)) { + if (policy('delete', 'domain', array('prefid' => $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 name array in post data' + )); + } + } + else { + echo json_encode(array( + 'type' => 'error', + 'msg' => 'Cannot find items in post data' + )); + } + break; case "time_limited_alias": if (isset($_POST['items'])) { $items = (array)json_decode($_POST['items'], true); @@ -1509,6 +1862,50 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u )); } break; + case "fwdhost": + 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('fwdhost' => $items), $attr); + if (is_array($postarray['fwdhost'])) { + if (fwdhost('edit', $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 "admin": // No items as there is only one admin if (isset($_POST['attr'])) { diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index 5c2936db..2969f812 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -20,7 +20,7 @@ $lang['danger']['dkim_remove_failed'] = "Cannot remove selected DKIM key"; $lang['danger']['dkim_add_failed'] = "Cannot add given DKIM key"; $lang['danger']['dkim_domain_or_sel_invalid'] = "DKIM domain or selector invalid"; $lang['danger']['dkim_key_length_invalid'] = "DKIM key length invalid"; -$lang['success']['dkim_removed'] = "DKIM key has been removed"; +$lang['success']['dkim_removed'] = "DKIM key %s has been removed"; $lang['success']['dkim_added'] = "DKIM key has been saved"; $lang['danger']['access_denied'] = "Access denied or invalid form data"; $lang['danger']['whitelist_from_invalid'] = "Whitelist entry invalid"; @@ -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 "%s" 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)"; @@ -260,7 +260,7 @@ $lang['mailbox']['add_alias'] = 'Add alias'; $lang['mailbox']['add_domain_record_first'] = 'Please add a domain first'; $lang['mailbox']['empty'] = 'No results'; $lang['mailbox']['toggle_all'] = 'Toggle all'; -$lang['mailbox']['quick_actions'] = 'Quick actions'; +$lang['mailbox']['quick_actions'] = 'Actions'; $lang['mailbox']['activate'] = 'Activate'; $lang['mailbox']['deactivate'] = 'Deactivate'; diff --git a/data/web/mailbox.php b/data/web/mailbox.php index b10bb414..f7195f6e 100644 --- a/data/web/mailbox.php +++ b/data/web/mailbox.php @@ -31,7 +31,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI']; - + @@ -53,7 +53,8 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
    - + + @@ -61,7 +62,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
    - +

    @@ -80,7 +81,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
    - + @@ -88,7 +89,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
    - +

    @@ -107,7 +108,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
    - + @@ -115,7 +116,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
    - +

    @@ -134,14 +135,16 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
    - +
    - +
    + +

    @@ -159,7 +162,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
    - +
    @@ -167,7 +170,9 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI']; - +