From eb3fb6d1f8828ea531a95f06ace0a5eb9c56bc85 Mon Sep 17 00:00:00 2001 From: andryyy Date: Sat, 28 Jan 2017 09:53:39 +0100 Subject: [PATCH] Add resources --- data/web/add.php | 77 ++++-- data/web/css/mailbox.css | 3 + data/web/delete.php | 27 +- data/web/edit.php | 197 +++++++++------ data/web/inc/functions.inc.php | 442 +++++++++++++++++++++++++++++++-- data/web/inc/init.sql | 4 +- data/web/inc/triggers.inc.php | 10 +- data/web/js/mailbox.js | 2 + data/web/lang/lang.de.php | 23 +- data/web/lang/lang.en.php | 24 +- data/web/mailbox.php | 206 ++++++++++----- 11 files changed, 818 insertions(+), 197 deletions(-) diff --git a/data/web/add.php b/data/web/add.php index 45df8f4b..0bc7496b 100644 --- a/data/web/add.php +++ b/data/web/add.php @@ -188,30 +188,13 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
- +
@@ -253,6 +236,60 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm +

+
"> +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ diff --git a/data/web/css/mailbox.css b/data/web/css/mailbox.css index 48fa5e39..b5c69343 100644 --- a/data/web/css/mailbox.css +++ b/data/web/css/mailbox.css @@ -13,4 +13,7 @@ } .progress { margin-bottom: 0px; +} +.table>thead>tr>th { + vertical-align: top !important; } \ No newline at end of file diff --git a/data/web/delete.php b/data/web/delete.php index 5ba83e06..6ba93d31 100644 --- a/data/web/delete.php +++ b/data/web/delete.php @@ -112,7 +112,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm $mailbox = $_GET["mailbox"]; if (hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $mailbox)) { ?> - +

@@ -130,6 +130,31 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm + +

+ + +
+
+ +
+
+
+ + + diff --git a/data/web/edit.php b/data/web/edit.php index fcdb5734..fb382809 100644 --- a/data/web/edit.php +++ b/data/web/edit.php @@ -392,92 +392,132 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm } } elseif (isset($_GET['mailbox']) && filter_var($_GET["mailbox"], FILTER_VALIDATE_EMAIL) && !empty($_GET["mailbox"])) { - $mailbox = $_GET["mailbox"]; - $result = mailbox_get_mailbox_details($mailbox); + $mailbox = $_GET["mailbox"]; + $result = mailbox_get_mailbox_details($mailbox); + if (!empty($result)) { + ?> +

+
"> + +
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ -

+

"> - +
- +
- +
- +
- -
-
-
- -
- + + +
-
- -
- -
-
-
- -
- -
-
@@ -487,7 +527,14 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
- +
+ +
+
+
+
+
+
diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index 9ec3271e..f0677d53 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -203,8 +203,9 @@ function check_login($user, $pass) { } } $stmt = $pdo->prepare("SELECT `password` FROM `mailbox` - WHERE `active`='1' - AND `username` = :user"); + WHERE `kind` NOT REGEXP 'location|thing|group' + AND `active`='1' + AND `username` = :user"); $stmt->execute(array(':user' => $user)); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); foreach ($rows as $row) { @@ -555,7 +556,8 @@ function edit_user_account($postarray) { } $stmt = $pdo->prepare("SELECT `password` FROM `mailbox` - WHERE `username` = :user"); + WHERE `kind` NOT REGEXP 'location|thing|group' + AND `username` = :user"); $stmt->execute(array(':user' => $username)); $row = $stmt->fetch(PDO::FETCH_ASSOC); if (!verify_ssha256($row['password'], $password_old)) { @@ -1842,7 +1844,7 @@ function set_tfa($postarray) { case "u2f": try { $reg = $u2f->doRegister(json_decode($_SESSION['regReq']), json_decode($postarray['token'])); - $stmt = $pdo->prepare("INSERT INTO `tfa` (`username`, `authmech`, `keyHandle`, `publicKey`, `certificate`, `counter`) values (?, 'u2f', ?, ?, ?, ?)"); + $stmt = $pdo->prepare("INSERT INTO `tfa` (`username`, `authmech`, `keyHandle`, `publicKey`, `certificate`, `counter`) VALUES (?, 'u2f', ?, ?, ?, ?)"); $stmt->execute(array($username, $reg->keyHandle, $reg->publicKey, $reg->certificate, $reg->counter)); $_SESSION['return'] = array( 'type' => 'success', @@ -2573,6 +2575,19 @@ function mailbox_add_alias($postarray) { $goto_local_part = strstr($goto, '@', true); $goto = $goto_local_part.'@'.$goto_domain; + $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` + WHERE `kind` REGEXP 'location|thing|group' + AND `username`= :goto"); + $stmt->execute(array(':goto' => $goto)); + $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); + if ($num_results != 0) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['goto_invalid']) + ); + return false; + } + if (!filter_var($goto, FILTER_VALIDATE_EMAIL) === true) { $_SESSION['return'] = array( 'type' => 'danger', @@ -2806,7 +2821,8 @@ function mailbox_add_mailbox($postarray) { COUNT(*) as count, COALESCE(ROUND(SUM(`quota`)/1048576), 0) as `quota` FROM `mailbox` - WHERE `domain` = :domain"); + WHERE `kind` NOT REGEXP 'location|thing|group' + AND `domain` = :domain"); $stmt->execute(array(':domain' => $domain)); $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC); @@ -2950,7 +2966,147 @@ function mailbox_add_mailbox($postarray) { ); } catch (PDOException $e) { - mailbox_delete_mailbox(array('address' => $username)); + mailbox_delete_mailbox(array('username' => $username)); + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } +} +function mailbox_add_resource($postarray) { + // Array elements + // active int + // domain string + // description string + // multiple_bookings int + // kind string + + global $pdo; + global $lang; + $domain = idn_to_ascii(strtolower(trim($postarray['domain']))); + $description = $postarray['description']; + $local_part = preg_replace('/[^\da-z]/i', '', preg_quote($description, '/')); + $name = $local_part . '@' . $domain; + $kind = $postarray['kind']; + isset($postarray['active']) ? $active = '1' : $active = '0'; + isset($postarray['multiple_bookings']) ? $multiple_bookings = '1' : $multiple_bookings = '0'; + + if (!filter_var($name, FILTER_VALIDATE_EMAIL)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['resource_invalid']) + ); + return false; + } + + if (empty($description)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['description_invalid']) + ); + return false; + } + + if ($kind != 'location' && $kind != 'group' && $kind != 'thing') { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['resource_invalid']) + ); + return false; + } + + if (!is_valid_domain_name($domain)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['domain_invalid']) + ); + 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; + } + + try { + $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `username` = :name"); + $stmt->execute(array(':name' => $name)); + $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); + if ($num_results != 0) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['object_exists'], htmlspecialchars($name)) + ); + return false; + } + + $stmt = $pdo->prepare("SELECT `address` FROM `alias` WHERE address= :name"); + $stmt->execute(array(':name' => $name)); + $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); + if ($num_results != 0) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['is_alias'], htmlspecialchars($name)) + ); + return false; + } + + $stmt = $pdo->prepare("SELECT `address` FROM `spamalias` WHERE `address`= :name"); + $stmt->execute(array(':name' => $name)); + $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); + if ($num_results != 0) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['is_spam_alias'], htmlspecialchars($name)) + ); + return false; + } + + $stmt = $pdo->prepare("SELECT `domain` FROM `domain` WHERE `domain`= :domain"); + $stmt->execute(array(':domain' => $domain)); + $num_results = count($stmt->fetchAll(PDO::FETCH_ASSOC)); + if ($num_results == 0) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['domain_not_found'], $domain) + ); + return false; + } + } + catch(PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } + + try { + $stmt = $pdo->prepare("INSERT INTO `mailbox` (`username`, `password`, `name`, `maildir`, `quota`, `local_part`, `domain`, `created`, `modified`, `active`, `multiple_bookings`, `kind`) + VALUES (:name, 'RESOURCE', :description, 'RESOURCE', 0, :local_part, :domain, :created, :modified, :active, :multiple_bookings, :kind)"); + $stmt->execute(array( + ':name' => $name, + ':description' => $description, + ':local_part' => $local_part, + ':domain' => $domain, + ':created' => date('Y-m-d H:i:s'), + ':modified' => date('Y-m-d H:i:s'), + ':active' => $active, + ':kind' => $kind, + ':multiple_bookings' => $multiple_bookings + )); + + $_SESSION['return'] = array( + 'type' => 'success', + 'msg' => sprintf($lang['success']['resource_added'], htmlspecialchars($name)) + ); + } + catch (PDOException $e) { + mailbox_delete_resource(array('name' => $name)); $_SESSION['return'] = array( 'type' => 'danger', 'msg' => 'MySQL: '.$e @@ -3200,7 +3356,8 @@ function mailbox_edit_domain($postarray) { MAX(COALESCE(ROUND(`quota`/1048576), 0)) AS `maxquota`, COALESCE(ROUND(SUM(`quota`)/1048576), 0) AS `quota` FROM `mailbox` - WHERE domain= :domain"); + WHERE `kind` NOT REGEXP 'location|thing|group' + AND domain = :domain"); $stmt->execute(array(':domain' => $domain)); $MailboxData = $stmt->fetch(PDO::FETCH_ASSOC); // GET ALIAS DATA @@ -3562,6 +3719,78 @@ function mailbox_edit_mailbox($postarray) { return false; } } +function mailbox_edit_resource($postarray) { + global $lang; + global $pdo; + + isset($postarray['active']) ? $active = '1' : $active = '0'; + isset($postarray['multiple_bookings']) ? $multiple_bookings = '1' : $multiple_bookings = '0'; + $name = $postarray['name']; + $kind = $postarray['kind']; + $description = $postarray['description']; + + if (!filter_var($name, FILTER_VALIDATE_EMAIL)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['resource_invalid']) + ); + return false; + } + + if (empty($description)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['description_invalid']) + ); + return false; + } + + if ($kind != 'location' && $kind != 'group' && $kind != 'thing') { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['resource_invalid']) + ); + return false; + } + + if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $name)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + + try { + $stmt = $pdo->prepare("UPDATE `mailbox` SET + `modified` = :modified, + `active` = :active, + `name`= :description, + `kind`= :kind, + `multiple_bookings`= :multiple_bookings + WHERE `username` = :name"); + $stmt->execute(array( + ':active' => $active, + ':modified' => date('Y-m-d H:i:s'), + ':description' => $description, + ':multiple_bookings' => $multiple_bookings, + ':kind' => $kind, + ':name' => $name + )); + $_SESSION['return'] = array( + 'type' => 'success', + 'msg' => sprintf($lang['success']['resource_modified'], $name) + ); + return true; + } + catch (PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } +} function mailbox_get_mailboxes($domain = null) { global $lang; global $pdo; @@ -3575,7 +3804,7 @@ function mailbox_get_mailboxes($domain = null) { } elseif (isset($domain) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) { try { - $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `domain` != 'ALL' AND `domain` = :domain"); + $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` != 'ALL' AND `domain` = :domain"); $stmt->execute(array( ':domain' => $domain, )); @@ -3594,7 +3823,7 @@ function mailbox_get_mailboxes($domain = null) { } else { try { - $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role"); + $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role"); $stmt->execute(array( ':username' => $_SESSION['mailcow_cc_username'], ':role' => $_SESSION['mailcow_cc_role'], @@ -3614,6 +3843,58 @@ function mailbox_get_mailboxes($domain = null) { } return $mailboxes; } +function mailbox_get_resources($domain = null) { + global $lang; + global $pdo; + $resources = array(); + if (isset($domain) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + elseif (isset($domain) && hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) { + try { + $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `domain` != 'ALL' AND `domain` = :domain"); + $stmt->execute(array( + ':domain' => $domain, + )); + $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); + while($row = array_shift($rows)) { + $resources[] = $row['username']; + } + } + catch (PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } + } + else { + try { + $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `domain` IN (SELECT `domain` FROM `domain_admins` WHERE `active` = '1' AND `username` = :username) OR 'admin' = :role"); + $stmt->execute(array( + ':username' => $_SESSION['mailcow_cc_username'], + ':role' => $_SESSION['mailcow_cc_role'], + )); + $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); + while($row = array_shift($rows)) { + $resources[] = $row['username']; + } + } + catch (PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } + } + return $resources; +} function mailbox_get_alias_domains($domain = null) { // Get all domains assigned to mailcow_cc_username or domain, if set // Domain admin needs to be active @@ -3853,7 +4134,7 @@ function mailbox_get_domain_details($domain) { ':domain' => $domain, )); $row = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `domain` = :domain"); + $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` = :domain"); $stmt->execute(array(':domain' => $row['domain'])); $MailboxDataDomain = $stmt->fetch(PDO::FETCH_ASSOC); @@ -3901,6 +4182,13 @@ function mailbox_get_domain_details($domain) { function mailbox_get_mailbox_details($mailbox) { global $lang; global $pdo; + if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $mailbox)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } $mailboxdata = array(); try { $stmt = $pdo->prepare("SELECT @@ -3914,7 +4202,7 @@ function mailbox_get_mailbox_details($mailbox) { `quota2`.`bytes`, `quota2`.`messages` FROM `mailbox`, `quota2`, `domain` - WHERE `mailbox`.`username` = `quota2`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox"); + WHERE `mailbox`.`kind` NOT REGEXP 'location|thing|group' AND `mailbox`.`username` = `quota2`.`username` AND `domain`.`domain` = `mailbox`.`domain` AND `mailbox`.`username` = :mailbox"); $stmt->execute(array( ':mailbox' => $mailbox, )); @@ -3924,7 +4212,7 @@ function mailbox_get_mailbox_details($mailbox) { $stmt->execute(array(':domain' => $row['domain'])); $DomainQuota = $stmt->fetch(PDO::FETCH_ASSOC); - $stmt = $pdo->prepare("SELECT COUNT(*) AS `count`, COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `domain` = :domain AND `username` != :username"); + $stmt = $pdo->prepare("SELECT COALESCE(SUM(`quota`), 0) as `in_use` FROM `mailbox` WHERE `kind` NOT REGEXP 'location|thing|group' AND `domain` = :domain AND `username` != :username"); $stmt->execute(array(':domain' => $row['domain'], ':username' => $row['username'])); $MailboxUsage = $stmt->fetch(PDO::FETCH_ASSOC); @@ -3960,8 +4248,54 @@ function mailbox_get_mailbox_details($mailbox) { ); return false; } - if (!isset($mailboxdata['domain']) || - (isset($mailboxdata['domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $mailboxdata['domain']))) { + return $mailboxdata; +} +function mailbox_get_resource_details($resource) { + global $lang; + global $pdo; + $resourcedata = array(); + if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $resource)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + try { + $stmt = $pdo->prepare("SELECT + `username`, + `name`, + `kind`, + `multiple_bookings` AS `multiple_bookings_int`, + `local_part`, + `active` AS `active_int`, + CASE `multiple_bookings` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `multiple_bookings`, + CASE `active` WHEN 1 THEN '".$lang['mailbox']['yes']."' ELSE '".$lang['mailbox']['no']."' END AS `active`, + `domain` + FROM `mailbox` WHERE `kind` REGEXP 'location|thing|group' AND `username` = :resource"); + $stmt->execute(array( + ':resource' => $resource, + )); + $row = $stmt->fetch(PDO::FETCH_ASSOC); + $resourcedata['name'] = $row['username']; + $resourcedata['kind'] = $row['kind']; + $resourcedata['multiple_bookings'] = $row['multiple_bookings']; + $resourcedata['multiple_bookings_int'] = $row['multiple_bookings']; + $resourcedata['description'] = $row['name']; + $resourcedata['active'] = $row['active']; + $resourcedata['active_int'] = $row['active_int']; + $resourcedata['domain'] = $row['domain']; + $resourcedata['local_part'] = $row['local_part']; + } + catch (PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } + if (!isset($resourcedata['domain']) || + (isset($resourcedata['domain']) && !hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $resourcedata['domain']))) { $_SESSION['return'] = array( 'type' => 'danger', 'msg' => sprintf($lang['danger']['access_denied']) @@ -3969,7 +4303,7 @@ function mailbox_get_mailbox_details($mailbox) { return false; } - return $mailboxdata; + return $resourcedata; } function mailbox_delete_domain($postarray) { global $lang; @@ -3989,8 +4323,7 @@ function mailbox_delete_domain($postarray) { ); return false; } - $domain = strtolower(trim($domain)); - + $domain = idn_to_ascii(strtolower(trim($domain))); try { $stmt = $pdo->prepare("SELECT `username` FROM `mailbox` @@ -4113,6 +4446,7 @@ function mailbox_delete_alias($postarray) { function mailbox_delete_alias_domain($postarray) { global $lang; global $pdo; + $alias_domain = $postarray['alias_domain']; if (!is_valid_domain_name($postarray['alias_domain'])) { $_SESSION['return'] = array( 'type' => 'danger', @@ -4120,7 +4454,6 @@ function mailbox_delete_alias_domain($postarray) { ); return false; } - $alias_domain = $postarray['alias_domain']; try { $stmt = $pdo->prepare("SELECT `target_domain` FROM `alias_domain` WHERE `alias_domain`= :alias_domain"); @@ -4169,7 +4502,7 @@ function mailbox_delete_mailbox($postarray) { global $lang; global $pdo; $username = $postarray['username']; - $domain = mailbox_get_mailbox_details($username)['domain']; + if (!filter_var($postarray['username'], FILTER_VALIDATE_EMAIL)) { $_SESSION['return'] = array( 'type' => 'danger', @@ -4177,7 +4510,8 @@ function mailbox_delete_mailbox($postarray) { ); return false; } - if (!hasDomainAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $domain)) { + + if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $username)) { $_SESSION['return'] = array( 'type' => 'danger', 'msg' => sprintf($lang['danger']['access_denied']) @@ -4214,6 +4548,34 @@ function mailbox_delete_mailbox($postarray) { $stmt->execute(array( ':username' => $username )); + $stmt = $pdo->prepare("DELETE FROM `sogo_user_profile` WHERE `c_uid` = :username"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_cache_folder` WHERE `c_uid` = :username"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_acl` WHERE `c_object` LIKE '%/" . $username . "/%' OR `c_uid` = :username"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_store` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_quick_contact` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_quick_appointment` WHERE `c_folder_id` IN (SELECT `c_folder_id` FROM `sogo_folder_info` WHERE `c_path2` = :username)"); + $stmt->execute(array( + ':username' => $username + )); + $stmt = $pdo->prepare("DELETE FROM `sogo_folder_info` WHERE `c_path2` = :username"); + $stmt->execute(array( + ':username' => $username + )); $stmt = $pdo->prepare("SELECT `address`, `goto` FROM `alias` WHERE `goto` LIKE :username"); $stmt->execute(array(':username' => '%'.$username.'%')); @@ -4247,6 +4609,44 @@ function mailbox_delete_mailbox($postarray) { 'msg' => sprintf($lang['success']['mailbox_removed'], htmlspecialchars($username)) ); } +function mailbox_delete_resource($postarray) { + global $lang; + global $pdo; + $name = $postarray['name']; + if (!filter_var($postarray['name'], FILTER_VALIDATE_EMAIL)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + + if (!hasMailboxObjectAccess($_SESSION['mailcow_cc_username'], $_SESSION['mailcow_cc_role'], $name)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + + try { + $stmt = $pdo->prepare("DELETE FROM `mailbox` WHERE `username` = :name"); + $stmt->execute(array( + ':name' => $name + )); + } + catch (PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } + $_SESSION['return'] = array( + 'type' => 'success', + 'msg' => sprintf($lang['success']['resource_removed'], htmlspecialchars($name)) + ); +} function mailbox_get_sender_acl_handles($mailbox) { global $pdo; global $lang; @@ -4369,7 +4769,7 @@ function get_u2f_registrations($username) { function add_u2f_registration($username, $reg) { global $pdo; global $lang; - $ins = $pdo->prepare("INSERT INTO `tfa` (`username`, `authmech`, `keyHandle`, `publicKey`, `certificate`, `counter`) values (?, 'u2f', ?, ?, ?, ?)"); + $ins = $pdo->prepare("INSERT INTO `tfa` (`username`, `authmech`, `keyHandle`, `publicKey`, `certificate`, `counter`) VALUES (?, 'u2f', ?, ?, ?, ?)"); $ins->execute(array($username, $reg->keyHandle, $reg->publicKey, $reg->certificate, $reg->counter)); $_SESSION['return'] = array( 'type' => 'success', diff --git a/data/web/inc/init.sql b/data/web/inc/init.sql index 1bf9172c..b2cff817 100644 --- a/data/web/inc/init.sql +++ b/data/web/inc/init.sql @@ -205,7 +205,7 @@ CREATE TABLE IF NOT EXISTS sogo_folder_info ( UNIQUE KEY c_folder_id (c_folder_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; -CREATE TABLE IF NOT EXISTS sogo_quick_appoINTment ( +CREATE TABLE IF NOT EXISTS sogo_quick_appointment ( c_folder_id INTeger NOT NULL, c_name character varying(255) NOT NULL, c_uid character varying(255) NOT NULL, @@ -230,7 +230,7 @@ CREATE TABLE IF NOT EXISTS sogo_quick_appoINTment ( c_component character varying(10) NOT NULL, c_nextalarm INTeger, c_description TEXT, - CONSTRAINT sogo_quick_appoINTment_pkey PRIMARY KEY (c_folder_id, c_name) + CONSTRAINT sogo_quick_appointment_pkey PRIMARY KEY (c_folder_id, c_name) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC; CREATE TABLE IF NOT EXISTS sogo_quick_contact ( diff --git a/data/web/inc/triggers.inc.php b/data/web/inc/triggers.inc.php index feb301fb..3e68c87f 100644 --- a/data/web/inc/triggers.inc.php +++ b/data/web/inc/triggers.inc.php @@ -130,8 +130,8 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm if (isset($_POST["mailbox_add_mailbox"])) { mailbox_add_mailbox($_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); @@ -145,6 +145,9 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm if (isset($_POST["mailbox_edit_alias_domain"])) { mailbox_edit_alias_domain($_POST); } + if (isset($_POST["mailbox_edit_resource"])) { + mailbox_edit_resource($_POST); + } if (isset($_POST["trigger_delete_policy_list_item"])) { delete_policy_list_item($_POST); } @@ -160,5 +163,8 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm if (isset($_POST["mailbox_delete_mailbox"])) { mailbox_delete_mailbox($_POST); } + if (isset($_POST["mailbox_delete_resource"])) { + mailbox_delete_resource($_POST); + } } ?> diff --git a/data/web/js/mailbox.js b/data/web/js/mailbox.js index 443e05e5..d12a37c3 100644 --- a/data/web/js/mailbox.js +++ b/data/web/js/mailbox.js @@ -5,10 +5,12 @@ $(document).ready(function() { var rowCountDomain = $('#domaintable >tbody >#data').length; var rowCountMailbox = $('#mailboxtable >tbody >#data').length; var rowCountAlias = $('#aliastable >tbody >#data').length; + var rowCountResource = $('#resourcetable >tbody >#data').length; $("#numRowsDomainAlias").text(rowCountDomainAlias); $("#numRowsDomain").text(rowCountDomain); $("#numRowsMailbox").text(rowCountMailbox); $("#numRowsAlias").text(rowCountAlias); + $("#numRowsResource").text(rowCountResource); // Filter table function $.fn.extend({ diff --git a/data/web/lang/lang.de.php b/data/web/lang/lang.de.php index 30951df0..6b6f5ab8 100644 --- a/data/web/lang/lang.de.php +++ b/data/web/lang/lang.de.php @@ -39,6 +39,7 @@ $lang['success']['alias_added'] = 'Alias-Adresse(n) wurden angelegt'; $lang['success']['alias_modified'] = 'Änderungen an Alias %s wurden gespeichert'; $lang['success']['aliasd_modified'] = 'Änderungen an Alias-Domain %s wurden gespeichert'; $lang['success']['mailbox_modified'] = 'Änderungen an Mailbox %s wurden gespeichert'; +$lang['success']['resource_modified'] = "Änderungen an Ressource %s wurden gespeichert"; $lang['success']['object_modified'] = "Änderungen an Objekt %s wurden gespeichert"; $lang['success']['msg_size_saved'] = 'Limit wurde gesetzt'; $lang['danger']['aliasd_not_found'] = 'Alias-Domain nicht gefunden'; @@ -59,10 +60,9 @@ $lang['danger']['password_complexity'] = 'Passwort entspricht nicht den Vorgaben $lang['danger']['password_empty'] = 'Passwort darf nicht leer sein'; $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['info']['fetchmail_planned'] = 'Aufgabe zur Mailabholung wurde geplant. Bitte prüfen Sie den Vorgangsstatus zu einem späteren Zeitpunkt noch einmal.'; -$lang['danger']['fetchmail_source_empty'] = 'Bitte geben Sie einen Quell-Ordner an'; -$lang['danger']['fetchmail_dest_empty'] = 'Bitte geben Sie einen Ziel-Ordner an'; $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'; @@ -72,11 +72,13 @@ $lang['danger']['max_mailbox_exceeded'] = 'Anzahl an Mailboxen überschritten (% $lang['danger']['mailbox_quota_exceeded'] = 'Speicherplatz überschreitet das Limit (max. %d MiB)'; $lang['danger']['mailbox_quota_left_exceeded'] = 'Nicht genügend Speicherplatz vorhanden (Speicherplatz anwendbar: %d MiB)'; $lang['success']['mailbox_added'] = 'Mailbox %s wurde angelegt'; +$lang['success']['resource_added'] = 'Ressource %s wurde angelegt'; $lang['success']['domain_removed'] = 'Domain %s wurde entfernt'; $lang['success']['alias_removed'] = 'Alias-Adresse %s wurde entfernt'; $lang['success']['alias_domain_removed'] = 'Alias-Domain %s wurde entfernt'; $lang['success']['domain_admin_removed'] = 'Domain-Administrator %s wurde entfernt'; $lang['success']['mailbox_removed'] = 'Mailbox %s wurde entfernt'; +$lang['success']['resource_removed'] = 'Ressource %s wurde entfernt'; $lang['danger']['max_quota_in_use'] = 'Mailbox Speicherplatzlimit muss größer oder gleich %d MiB sein'; $lang['danger']['domain_quota_m_in_use'] = 'Domain Speicherplatzlimit muss größer oder gleich %d MiB sein'; $lang['danger']['mailboxes_in_use'] = 'Maximale Anzahl an Mailboxen muss größer oder gleich %d sein'; @@ -85,7 +87,6 @@ $lang['danger']['sender_acl_invalid'] = 'Sender ACL Wert muss eine Adresse oder $lang['danger']['domain_not_empty'] = 'Kann nur leere Domains entfernen'; $lang['warning']['spam_alias_temp_error'] = 'Kann zur Zeit keinen Spam-Alias erstellen, bitte versuchen Sie es später noch einmal.'; $lang['danger']['spam_alias_max_exceeded'] = 'Maximale Anzahl an Spam-Alias-Adressen erreicht'; -$lang['danger']['fetchmail_active'] = 'Ein Vorgang zur Mailabholung ist bereits aktiv, bitte haben Sie etwas Geduld.'; $lang['danger']['validity_missing'] = 'Bitte geben Sie eine Gültigkeitsdauer an'; $lang['user']['on'] = 'Ein'; $lang['user']['off'] = 'Aus'; @@ -203,6 +204,10 @@ $lang['header']['locale'] = 'Sprache'; $lang['mailbox']['domain'] = 'Domain'; $lang['mailbox']['alias'] = 'Alias'; $lang['mailbox']['aliases'] = 'Aliasse'; +$lang['mailbox']['multiple_bookings'] = 'Mehrfachbuchen'; +$lang['mailbox']['kind'] = 'Art'; +$lang['mailbox']['description'] = 'Beschreibung'; +$lang['mailbox']['resource_name'] = 'Ressourcenname'; $lang['mailbox']['domains'] = 'Domains'; $lang['mailbox']['mailboxes'] = 'Mailboxen'; $lang['mailbox']['mailbox_quota'] = 'Max. Größe einer Mailbox'; @@ -230,6 +235,7 @@ $lang['mailbox']['no_record_single'] = 'Kein Eintrag'; $lang['mailbox']['add_domain'] = 'Domain hinzufügen'; $lang['mailbox']['add_domain_alias'] = 'Domain-Alias hinzufügen'; $lang['mailbox']['add_mailbox'] = 'Mailbox hinzufügen'; +$lang['mailbox']['add_resource'] = 'Ressource hinzufügen'; $lang['mailbox']['add_alias'] = 'Alias hinzufügen'; $lang['info']['no_action'] = 'Keine Aktion anwendbar'; @@ -242,6 +248,8 @@ $lang['delete']['remove_alias_warning'] = 'Warnung: Sie entfernen die Ali $lang['delete']['remove_syncjob_warning'] = 'Warnung: Sie entfernen einen Sync-Job des Benutzers %s!'; $lang['delete']['remove_mailbox_warning'] = 'Warnung: Sie entfernen die Mailbox %s!'; $lang['delete']['remove_mailbox_details'] = 'Die Mailbox wird vollständig und permanent entfernt!'; +$lang['delete']['remove_resource_warning'] = 'Warnung: Sie entfernen die Ressource %s!'; +$lang['delete']['remove_resource_details'] = 'Die Ressource wird vollständig und permanent entfernt!'; $lang['delete']['remove_domain_details'] = 'Diese Aktion entfernt ebenfalls Domain-Aliasse.

Eine Domain muss leer sein, um entfernt zu werden.'; $lang['delete']['remove_syncjob_details'] = 'Objekte dieses Sync-Jobs werden nicht mehr vom entfernten Server abgeholt.'; $lang['delete']['remove_alias_details'] = 'Benutzer werden keine Nachrichten mehr von dieser Adresse erhalten und versenden koennen!'; @@ -294,6 +302,9 @@ $lang['edit']['dkim_txt_value'] = 'TXT-Record Wert:'; $lang['edit']['previous'] = 'Vorherige Seite'; $lang['edit']['unchanged_if_empty'] = 'Unverändert, wenn leer'; $lang['edit']['dont_check_sender_acl'] = 'Absender für Domain %s nicht prüfen'; +$lang['edit']['multiple_bookings'] = 'Mehrfaches Buchen'; +$lang['edit']['kind'] = 'Art'; +$lang['edit']['resource'] = 'Ressource'; $lang['add']['syncjob'] = 'Sync-Job erstellen'; $lang['add']['syncjob_hint'] = 'Passwörter werden unverschlüsselt abgelegt!'; @@ -309,6 +320,7 @@ $lang['add']['delete2duplicates'] = 'Lösche Duplikate im Ziel'; $lang['add']['title'] = 'Objekt anlegen'; $lang['add']['domain'] = 'Domain'; $lang['add']['active'] = 'Aktiv'; +$lang['add']['multiple_bookings'] = 'Mehrfaches Buchen möglich'; $lang['add']['save'] = 'Änderungen speichern'; $lang['add']['description'] = 'Beschreibung:'; $lang['add']['max_aliases'] = 'Max. mögliche Aliasse:'; @@ -330,7 +342,10 @@ $lang['add']['alias_domain'] = 'Alias-Domain'; $lang['add']['select'] = 'Bitte auswählen'; $lang['add']['target_domain'] = 'Ziel-Domain:'; $lang['add']['mailbox'] = 'Mailbox'; +$lang['add']['resource'] = 'Ressource'; +$lang['add']['kind'] = 'Art'; $lang['add']['mailbox_username'] = 'Benutzername (linker Teil der E-Mail-Adresse):'; +$lang['add']['resource_name'] = 'Ressourcenname:'; $lang['add']['full_name'] = 'Vor- und Zuname:'; $lang['add']['quota_mb'] = 'Speicherplatz (MiB):'; $lang['add']['select_domain'] = 'Bitte zuerst eine Domain auswählen'; diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index a5b94f16..ed60a7f6 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -41,6 +41,7 @@ $lang['success']['alias_added'] = "Alias address/es has/have been added"; $lang['success']['alias_modified'] = "Changes to alias have been saved"; $lang['success']['aliasd_modified'] = "Changes to alias domain have been saved"; $lang['success']['mailbox_modified'] = "Changes to mailbox %s have been saved"; +$lang['success']['resource_modified'] = "Changes to mailbox %s have been saved"; $lang['success']['object_modified'] = "Changes to object %s have been saved"; $lang['success']['msg_size_saved'] = "Message size limit has been set"; $lang['danger']['aliasd_not_found'] = "Alias domain not found"; @@ -61,10 +62,9 @@ $lang['danger']['password_complexity'] = "Password does not meet requirements (u $lang['danger']['password_empty'] = "Password must not be empty"; $lang['danger']['login_failed'] = "Login failed"; $lang['danger']['mailbox_invalid'] = "Mailbox name is invalid"; +$lang['danger']['description_invalid'] = 'Resource description is invalid'; +$lang['danger']['resource_invalid'] = "Resource name is invalid"; $lang['danger']['mailbox_invalid_suggest'] = 'Mailbox name is invalid, did you mean to type "%s"?'; -$lang['info']['fetchmail_planned'] = "Task to fetch emails has been planned. Please check the process at a later time."; -$lang['danger']['fetchmail_source_empty'] = "Please define a source folder"; -$lang['danger']['fetchmail_dest_empty'] = "Please define a target folder"; $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"; @@ -74,11 +74,13 @@ $lang['danger']['max_mailbox_exceeded'] = "Max. mailboxes exceeded (%d of %d)"; $lang['danger']['mailbox_quota_exceeded'] = "Quota exceeds the domain limit (max. %d MiB)"; $lang['danger']['mailbox_quota_left_exceeded'] = "Not enough space left (space left: %d MiB)"; $lang['success']['mailbox_added'] = "Mailbox %s has been added"; +$lang['success']['resource_added'] = "Resource %s has been added"; $lang['success']['domain_removed'] = "Domain %s has been removed"; $lang['success']['alias_removed'] = "Alias-Adresse %s has been removed"; $lang['success']['alias_domain_removed'] = "Alias domain %s has been removed"; $lang['success']['domain_admin_removed'] = "Domain administrator %s has been removed"; $lang['success']['mailbox_removed'] = "Mailbox %s has been removed"; +$lang['success']['resource_removed'] = "Resource %s has been removed"; $lang['danger']['max_quota_in_use'] = "Mailbox quota must be greater or equal to %d MiB"; $lang['danger']['domain_quota_m_in_use'] = "Domain quota must be greater or equal to %s MiB"; $lang['danger']['mailboxes_in_use'] = "Max. mailboxes must be greater or equal to %d"; @@ -87,9 +89,7 @@ $lang['danger']['sender_acl_invalid'] = "Sender ACL value is invalid"; $lang['danger']['domain_not_empty'] = "Cannot remove non-empty domain"; $lang['warning']['spam_alias_temp_error'] = "Temporary error: Cannot add spam alias, please try again later."; $lang['danger']['spam_alias_max_exceeded'] = "Max. allowed spam alias addresses exceeded"; -$lang['danger']['fetchmail_active'] = "A process is already running, please wait for it to finish."; $lang['danger']['validity_missing'] = 'Please assign a period of validity'; -$lang['danger']['tfa_token_invalid'] = 'TFA token is invalid'; $lang['user']['on'] = "On"; $lang['user']['off'] = "Off"; $lang['user']['user_change_fn'] = ""; @@ -204,7 +204,11 @@ $lang['header']['logged_in_as_logout'] = 'Logged in as %s (logout)'; $lang['header']['logged_in_as_logout_dual'] = 'Logged in as %s [%s]'; $lang['header']['locale'] = 'Language'; $lang['mailbox']['domain'] = 'Domain'; +$lang['mailbox']['multiple_bookings'] = 'Multiple bookings'; +$lang['mailbox']['kind'] = 'Kind'; +$lang['mailbox']['description'] = 'Description'; $lang['mailbox']['alias'] = 'Alias'; +$lang['mailbox']['resource_name'] = 'Resource name'; $lang['mailbox']['aliases'] = 'Aliases'; $lang['mailbox']['domains'] = 'Domains'; $lang['mailbox']['mailboxes'] = 'Mailboxes'; @@ -233,6 +237,7 @@ $lang['mailbox']['no_record_single'] = 'No record'; $lang['mailbox']['add_domain'] = 'Add domain'; $lang['mailbox']['add_domain_alias'] = 'Add domain alias'; $lang['mailbox']['add_mailbox'] = 'Add mailbox'; +$lang['mailbox']['add_resource'] = 'Add resource'; $lang['mailbox']['add_alias'] = 'Add alias'; $lang['info']['no_action'] = 'No action applicable'; @@ -245,6 +250,8 @@ $lang['delete']['remove_domainadmin_warning'] = 'Warning: You are about t $lang['delete']['remove_alias_warning'] = 'Warning: You are about to remove the alias address %s!'; $lang['delete']['remove_mailbox_warning'] = 'Warning: You are about to remove the mailbox %s!'; $lang['delete']['remove_mailbox_details'] = 'The mailbox will be purged permanently!'; +$lang['delete']['remove_resource_warning'] = 'Warning: You are about to remove the resource %s!'; +$lang['delete']['remove_resource_details'] = 'The resource will be purged permanently!'; $lang['delete']['remove_domain_details'] = 'This also removes domain aliases.

A domain must be empty to be removed.'; $lang['delete']['remove_syncjob_details'] = 'Objects from this sync job will not be pulled from the remote server anymore.'; $lang['delete']['remove_alias_details'] = 'Users will no longer be able to receive mail for or send mail from this address.'; @@ -298,6 +305,9 @@ $lang['edit']['dkim_txt_value'] = 'TXT record value:'; $lang['edit']['previous'] = 'Previous page'; $lang['edit']['unchanged_if_empty'] = 'If unchanged leave blank'; $lang['edit']['dont_check_sender_acl'] = 'Do not check sender for domain %s'; +$lang['edit']['multiple_bookings'] = 'Multiple bookings'; +$lang['edit']['kind'] = 'Kind'; +$lang['edit']['resource'] = 'Resource'; $lang['add']['syncjob'] = 'Add sync job'; $lang['add']['syncjob_hint'] = 'Be aware that passwords need to be saved plain-text!'; @@ -313,9 +323,11 @@ $lang['add']['delete2duplicates'] = 'Delete duplicates on destination'; $lang['add']['title'] = 'Add object'; $lang['add']['domain'] = 'Domain'; $lang['add']['active'] = 'Active'; +$lang['add']['multiple_bookings'] = 'Multiple bookings'; $lang['add']['save'] = 'Save changes'; $lang['add']['description'] = 'Description:'; $lang['add']['max_aliases'] = 'Max. possible aliases:'; +$lang['add']['resource_name'] = 'Resource name'; $lang['add']['max_mailboxes'] = 'Max. possible mailboxes:'; $lang['add']['mailbox_quota_m'] = 'Max. quota per mailbox (MiB):'; $lang['add']['domain_quota_m'] = 'Total domain quota (MiB):'; @@ -334,6 +346,8 @@ $lang['add']['alias_domain'] = 'Alias domain'; $lang['add']['select'] = 'Please select...'; $lang['add']['target_domain'] = 'Target domain:'; $lang['add']['mailbox'] = 'Mailbox'; +$lang['add']['resource'] = 'Resource'; +$lang['add']['kind'] = 'Kind'; $lang['add']['mailbox_username'] = 'Username (left part of an email address):'; $lang['add']['full_name'] = 'Full name:'; $lang['add']['quota_mb'] = 'Quota (MiB):'; diff --git a/data/web/mailbox.php b/data/web/mailbox.php index d83c89dd..c6c84656 100644 --- a/data/web/mailbox.php +++ b/data/web/mailbox.php @@ -114,73 +114,6 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
-
-
-
-
-

-
- - - - -
-
-
- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - -
-
- -
-
-
-
-
@@ -265,6 +198,145 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
+
+
+
+
+

Resources

+
+ + + + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ +
+
+
+
+
+
+
+
+
+

+
+ + + + +
+
+
+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + +
+
+ +
+
+
+
+
+