From 66e9833c911f5083d57cca57489ffb69a8e6a86d Mon Sep 17 00:00:00 2001 From: andryyy <andre.peters@debinux.de> Date: Sun, 22 Jan 2017 16:41:45 +0100 Subject: [PATCH] More work on web UI --- data/web/add.php | 8 +- data/web/admin.php | 33 ++----- data/web/css/mailbox.css | 16 ++++ data/web/css/mailcow.css | 45 ++++++++++ data/web/css/tables.css | 79 +++++++++++++++++ data/web/delete.php | 8 +- data/web/edit.php | 16 ++-- data/web/inc/admin.inc.php | 146 +++++++++++++++++++++++++++++++ data/web/inc/functions.inc.php | 41 ++++++++- data/web/inc/header.inc.php | 152 +-------------------------------- data/web/inc/mailbox.inc.php | 24 +++++- data/web/lang/lang.en.php | 8 +- data/web/user.php | 51 ++++++----- 13 files changed, 401 insertions(+), 226 deletions(-) create mode 100644 data/web/css/mailbox.css create mode 100644 data/web/css/mailcow.css create mode 100644 data/web/css/tables.css create mode 100644 data/web/inc/admin.inc.php diff --git a/data/web/add.php b/data/web/add.php index 5d28d88b..45df8f4b 100644 --- a/data/web/add.php +++ b/data/web/add.php @@ -77,7 +77,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="adddomain" class="btn btn-success"><?=$lang['add']['save'];?></button> + <button type="submit" name="mailbox_add_domain" class="btn btn-success"><?=$lang['add']['save'];?></button> </div> </div> <p><span class="glyphicon glyphicon-exclamation-sign text-danger"></span> <?=$lang['add']['restart_sogo_hint'];?></p> @@ -112,7 +112,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="addalias" class="btn btn-success "><?=$lang['add']['save'];?></button> + <button type="submit" name="mailbox_add_alias" class="btn btn-success "><?=$lang['add']['save'];?></button> </div> </div> </form> @@ -167,7 +167,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="addaliasdomain" class="btn btn-success "><?=$lang['add']['save'];?></button> + <button type="submit" name="mailbox_add_alias_domain" class="btn btn-success "><?=$lang['add']['save'];?></button> </div> </div> </form> @@ -247,7 +247,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="addmailbox" class="btn btn-success "><?=$lang['add']['save'];?></button> + <button type="submit" name="mailbox_add_mailbox" class="btn btn-success "><?=$lang['add']['save'];?></button> </div> </div> </form> diff --git a/data/web/admin.php b/data/web/admin.php index 1845bcb5..c6f78a89 100644 --- a/data/web/admin.php +++ b/data/web/admin.php @@ -13,25 +13,12 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI']; <div class="panel-heading"><?=$lang['admin']['admin_details'];?></div> <div class="panel-body"> <form class="form-horizontal" autocapitalize="none" autocorrect="off" role="form" method="post"> - <?php - try { - $stmt = $pdo->prepare("SELECT `username` FROM `admin` - WHERE `superadmin`='1' and active='1'"); - $stmt->execute(); - $AdminData = $stmt->fetch(PDO::FETCH_ASSOC); - } - catch(PDOException $e) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => 'MySQL: '.$e - ); - } - ?> - <input type="hidden" name="admin_user_now" value="<?=htmlspecialchars($AdminData['username']);?>"> + <?php $admindetails = get_admin_details(); ?> + <input type="hidden" name="admin_user_now" value="<?=htmlspecialchars($admindetails['username']);?>"> <div class="form-group"> <label class="control-label col-sm-2" for="admin_user"><?=$lang['admin']['admin'];?>:</label> <div class="col-sm-10"> - <input type="text" class="form-control" name="admin_user" id="admin_user" value="<?=htmlspecialchars($AdminData['username']);?>" required> + <input type="text" class="form-control" name="admin_user" id="admin_user" value="<?=htmlspecialchars($admindetails['username']);?>" required> ↳ <kbd>a-z A-Z - _ .</kbd> </div> </div> @@ -124,18 +111,8 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI']; <div class="col-sm-10"> <select title="<?=$lang['admin']['search_domain_da'];?>" style="width:100%" name="domain[]" size="5" multiple> <?php - try { - $stmt = $pdo->query("SELECT domain FROM domain"); - $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); - } - catch(PDOException $e) { - $_SESSION['return'] = array( - 'type' => 'danger', - 'msg' => 'MySQL: '.$e - ); - } - while ($row = array_shift($rows)) { - echo "<option>".htmlspecialchars($row['domain'])."</option>"; + foreach (mailbox_get_domains() as $domain) { + echo "<option>".htmlspecialchars($domain)."</option>"; } ?> </select> diff --git a/data/web/css/mailbox.css b/data/web/css/mailbox.css new file mode 100644 index 00000000..48fa5e39 --- /dev/null +++ b/data/web/css/mailbox.css @@ -0,0 +1,16 @@ +.panel-heading div { + margin-top: -18px; + font-size: 15px; +} +.panel-heading div span { + margin-left:5px; +} +.panel-body { + display: none; +} +.clickable { + cursor: pointer; +} +.progress { + margin-bottom: 0px; +} \ No newline at end of file diff --git a/data/web/css/mailcow.css b/data/web/css/mailcow.css new file mode 100644 index 00000000..ee0b5cc6 --- /dev/null +++ b/data/web/css/mailcow.css @@ -0,0 +1,45 @@ +#maxmsgsize { min-width: 80px; } +#slider1 .slider-selection { + background: #FFD700; +} +#slider1 .slider-track-high { + background: #FF4500; +} +#slider1 .slider-track-low { + background: #66CD00; +} +.striped:nth-child(odd) { + background-color: #fff; +} +.striped:nth-child(even) { + background-color: #fafafa; + border:1px solid white; +} +.btn { + text-transform: none; +} +.glyphicon-spin { + -webkit-animation: spin 1000ms infinite linear; + animation: spin 1000ms infinite linear; +} +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); + transform: rotate(0deg); + } + 100% { + -webkit-transform: rotate(359deg); + transform: rotate(359deg); + } +} +pre{white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;} \ No newline at end of file diff --git a/data/web/css/tables.css b/data/web/css/tables.css new file mode 100644 index 00000000..651e1665 --- /dev/null +++ b/data/web/css/tables.css @@ -0,0 +1,79 @@ +ul[id*="sortable"] { word-wrap: break-word; list-style-type: none; float: left; padding: 0 15px 0 0; width: 48%; cursor:move} +ul[id$="sortable-active"] li {cursor:move; } +ul[id$="sortable-inactive"] li {cursor:move } +.list-heading { cursor:default !important} +.ui-state-disabled { cursor:no-drop; color:#ccc; } +.ui-state-highlight {background: #F5F5F5 !important; height: 41px !important; cursor:move } +table[data-sortable] { + border-collapse: collapse; + border-spacing: 0; +} +table[data-sortable] th { + vertical-align: bottom; + font-weight: bold; +} +table[data-sortable] th, table[data-sortable] td { + text-align: left; + padding: 10px; +} +table[data-sortable] th:not([data-sortable="false"]) { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); + -webkit-touch-callout: none; + cursor: pointer; +} +table[data-sortable] th:after { + content: ""; + visibility: hidden; + display: inline-block; + vertical-align: inherit; + height: 0; + width: 0; + border-width: 5px; + border-style: solid; + border-color: transparent; + margin-right: 1px; + margin-left: 10px; + float: right; +} +table[data-sortable] th[data-sortable="false"]:after { + display: none; +} +table[data-sortable] th[data-sorted="true"]:after { + visibility: visible; +} +table[data-sortable] th[data-sorted-direction="descending"]:after { + border-top-color: inherit; + margin-top: 8px; +} +table[data-sortable] th[data-sorted-direction="ascending"]:after { + border-bottom-color: inherit; + margin-top: 3px; +} +table[data-sortable].sortable-theme-bootstrap thead th { + border-bottom: 2px solid #e0e0e0; +} +table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"] { + color: #3a87ad; + background: #d9edf7; + border-bottom-color: #bce8f1; +} +table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"][data-sorted-direction="descending"]:after { + border-top-color: #3a87ad; +} +table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"][data-sorted-direction="ascending"]:after { + border-bottom-color: #3a87ad; +} +table[data-sortable].sortable-theme-bootstrap.sortable-theme-bootstrap-striped tbody > tr:nth-child(odd) > td { + background-color: #f9f9f9; +} +#data td, #no-data td { + vertical-align: middle; +} +.sort-table:hover { + border-bottom-color: #00B7DC !important; +} \ No newline at end of file diff --git a/data/web/delete.php b/data/web/delete.php index 86ac4764..5ba83e06 100644 --- a/data/web/delete.php +++ b/data/web/delete.php @@ -30,7 +30,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm <input type="hidden" name="domain" value="<?php echo htmlspecialchars($domain) ?>"> <div class="form-group"> <div class="col-sm-offset-1 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="deletedomain" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button> + <button type="submit" name="mailbox_delete_domain" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button> </div> </div> </form> @@ -49,7 +49,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm <input type="hidden" name="address" value="<?php echo htmlspecialchars($_GET["alias"]) ?>"> <div class="form-group"> <div class="col-sm-offset-1 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="deletealias" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button> + <button type="submit" name="mailbox_delete_alias" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button> </div> </div> </form> @@ -75,7 +75,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm <input type="hidden" name="alias_domain" value="<?php echo htmlspecialchars($alias_domain) ?>"> <div class="form-group"> <div class="col-sm-offset-1 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="deletealiasdomain" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button> + <button type="submit" name="mailbox_delete_alias_domain" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button> </div> </div> </form> @@ -118,7 +118,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm <input type="hidden" name="username" value="<?=htmlspecialchars($mailbox);?>"> <div class="form-group"> <div class="col-sm-offset-1 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="deletemailbox" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button> + <button type="submit" name="mailbox_delete_mailbox" class="btn btn-default btn-sm"><?=$lang['delete']['remove_button'];?></button> </div> </div> </form> diff --git a/data/web/edit.php b/data/web/edit.php index d9f54b4f..ce54a2af 100644 --- a/data/web/edit.php +++ b/data/web/edit.php @@ -42,7 +42,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="editalias" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button> + <button type="submit" name="mailbox_edit_alias" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button> </div> </div> </form> @@ -191,7 +191,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="editdomain" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button> + <button type="submit" name="mailbox_edit_domain" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button> </div> </div> </form> @@ -238,7 +238,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm if ($wl['object'] == $domain): ?> <input type="hidden" name="delete_prefid" value="<?=$wl['prefid'];?>"> - <input type="hidden" name="trigger_delete_policy_list_item"> + <input type="hidden" name="delete_policy_list_item"> <input type="hidden" name="domain" value="<?=$domain;?>"> <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a> <?php @@ -264,7 +264,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm <input type="hidden" name="domain" value="<?=$domain;?>"> </div> <div class="col-xs-6"> - <button type="submit" id="trigger_add_policy_list_item" name="trigger_add_policy_list_item" class="btn btn-xs btn-default"><?=$lang['user']['spamfilter_table_add'];?></button> + <button type="submit" name="add_policy_list_item" class="btn btn-xs btn-default"><?=$lang['user']['spamfilter_table_add'];?></button> </div> </form> </div> @@ -294,7 +294,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm <?php if ($bl['object'] == $domain): ?> - <input type="hidden" name="trigger_delete_policy_list_item"> + <input type="hidden" name="delete_policy_list_item"> <input type="hidden" name="domain" value="<?=$domain;?>"> <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a> <?php @@ -320,7 +320,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm <input type="hidden" name="domain" value="<?=$domain;?>"> </div> <div class="col-xs-6"> - <button type="submit" id="trigger_add_policy_list_item" name="trigger_add_policy_list_item" class="btn btn-xs btn-default"><?=$lang['user']['spamfilter_table_add'];?></button> + <button type="submit" name="add_policy_list_item" class="btn btn-xs btn-default"><?=$lang['user']['spamfilter_table_add'];?></button> </div> </form> </div> @@ -359,7 +359,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="editaliasdomain" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button> + <button type="submit" name="mailbox_edit_alias_domain" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button> </div> </div> </form> @@ -480,7 +480,7 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> - <button type="submit" name="trigger_mailbox_action" value="editmailbox" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button> + <button type="submit" name="mailbox_edit_mailbox" class="btn btn-success btn-sm"><?=$lang['edit']['save'];?></button> </div> </div> </form> diff --git a/data/web/inc/admin.inc.php b/data/web/inc/admin.inc.php new file mode 100644 index 00000000..d77d225d --- /dev/null +++ b/data/web/inc/admin.inc.php @@ -0,0 +1,146 @@ +<?php +function get_admin_details() { + // No parameter to be given, only one admin should exist + global $pdo; + global $lang; + $data = array(); + if ($_SESSION['mailcow_cc_role'] != 'admin') { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + try { + $stmt = $pdo->prepare("SELECT `username`, `modified`, `created` FROM `admin`WHERE `superadmin`='1' AND active='1'"); + $stmt->execute(); + $data = $stmt->fetch(PDO::FETCH_ASSOC); + } + catch(PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + } + return $data; +} +function edit_admin($postarray) { + global $lang; + global $pdo; + $username = $postarray['username']; + $password = $postarray['password']; + $password2 = $postarray['password2']; + isset($postarray['active']) ? $active = '1' : $active = '0'; + + if ($_SESSION['mailcow_cc_role'] != "admin") { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + + if(isset($postarray['domain'])) { + foreach ($postarray['domain'] as $domain) { + if (!is_valid_domain_name($domain)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['domain_invalid']) + ); + return false; + } + } + } + + if (!ctype_alnum(str_replace(array('_', '.', '-'), '', $username))) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['username_invalid']) + ); + return false; + } + + try { + $stmt = $pdo->prepare("DELETE FROM `domain_admins` WHERE `username` = :username"); + $stmt->execute(array( + ':username' => $username, + )); + } + catch (PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } + + if(isset($postarray['domain'])) { + foreach ($postarray['domain'] as $domain) { + try { + $stmt = $pdo->prepare("INSERT INTO `domain_admins` (`username`, `domain`, `created`, `active`) + VALUES (:username, :domain, :created, :active)"); + $stmt->execute(array( + ':username' => $username, + ':domain' => $domain, + ':created' => date('Y-m-d H:i:s'), + ':active' => $active + )); + } + catch (PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } + } + } + + if (!empty($password) && !empty($password2)) { + if ($password != $password2) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['password_mismatch']) + ); + return false; + } + $password_hashed = hash_password($password); + try { + $stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `active` = :active, `password` = :password_hashed WHERE `username` = :username"); + $stmt->execute(array( + ':password_hashed' => $password_hashed, + ':username' => $username, + ':modified' => date('Y-m-d H:i:s'), + ':active' => $active + )); + } + catch (PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } + } + else { + try { + $stmt = $pdo->prepare("UPDATE `admin` SET `modified` = :modified, `active` = :active WHERE `username` = :username"); + $stmt->execute(array( + ':username' => $username, + ':modified' => date('Y-m-d H:i:s'), + ':active' => $active + )); + } + catch (PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } + } + $_SESSION['return'] = array( + 'type' => 'success', + 'msg' => sprintf($lang['success']['domain_admin_modified'], htmlspecialchars($username)) + ); +} \ No newline at end of file diff --git a/data/web/inc/functions.inc.php b/data/web/inc/functions.inc.php index cc19ffcf..4e591d2a 100644 --- a/data/web/inc/functions.inc.php +++ b/data/web/inc/functions.inc.php @@ -2,6 +2,7 @@ require_once 'dkim.inc.php'; require_once 'mailbox.inc.php'; require_once 'domainadmin.inc.php'; +require_once 'admin.inc.php'; function hash_password($password) { $salt_str = bin2hex(openssl_random_pseudo_bytes(8)); return "{SSHA256}".base64_encode(hash('sha256', $password . $salt_str, true) . $salt_str); @@ -433,11 +434,11 @@ function set_time_limited_aliases($postarray) { 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username)) ); break; - case "extend": + case "extendall": try { - $stmt = $pdo->prepare("UPDATE `spamalias` SET `validity` = (`validity` + 3600) - WHERE `goto` = :username - AND `validity` >= :validity"); + $stmt = $pdo->prepare("UPDATE `spamalias` SET `validity` = (`validity` + 3600) WHERE + `goto` = :username AND + `validity` >= :validity"); $stmt->execute(array( ':username' => $username, ':validity' => time(), @@ -455,6 +456,38 @@ function set_time_limited_aliases($postarray) { 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username)) ); break; + case "extend": + if (empty($postarray['item']) || !filter_var($postarray['item'], FILTER_VALIDATE_EMAIL)) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => sprintf($lang['danger']['access_denied']) + ); + return false; + } + $item = $postarray['item']; + try { + $stmt = $pdo->prepare("UPDATE `spamalias` SET `validity` = (`validity` + 3600) WHERE + `goto` = :username AND + `address` = :item AND + `validity` >= :validity"); + $stmt->execute(array( + ':username' => $username, + ':item' => $item, + ':validity' => time(), + )); + } + catch (PDOException $e) { + $_SESSION['return'] = array( + 'type' => 'danger', + 'msg' => 'MySQL: '.$e + ); + return false; + } + $_SESSION['return'] = array( + 'type' => 'success', + 'msg' => sprintf($lang['success']['mailbox_modified'], htmlspecialchars($username)) + ); + break; } } function get_time_limited_aliases($username = null) { diff --git a/data/web/inc/header.inc.php b/data/web/inc/header.inc.php index 43e1119c..e2d0c865 100644 --- a/data/web/inc/header.inc.php +++ b/data/web/inc/header.inc.php @@ -17,157 +17,11 @@ <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/bootstrap-switch/3.3.2/css/bootstrap3/bootstrap-switch.min.css"> <link rel="stylesheet" href="//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600,700&subset=latin,latin-ext"> <link rel="stylesheet" href="/inc/languages.min.css"> +<link rel="stylesheet" href="/css/mailcow.css"> +<link rel="stylesheet" href="/css/tables.css"> +<?=(preg_match("/mailbox.php/i", $_SERVER['REQUEST_URI'])) ? '<link rel="stylesheet" href="/css/mailbox.css">' : null;?> <link rel="shortcut icon" href="/favicon.png" type="image/png"> <link rel="icon" href="/favicon.png" type="image/png"> -<style> -#maxmsgsize { min-width: 80px; } -ul[id*="sortable"] { word-wrap: break-word; list-style-type: none; float: left; padding: 0 15px 0 0; width: 48%; cursor:move} -ul[id$="sortable-active"] li {cursor:move; } -ul[id$="sortable-inactive"] li {cursor:move } -.list-heading { cursor:default !important} -.ui-state-disabled { cursor:no-drop; color:#ccc; } -.ui-state-highlight {background: #F5F5F5 !important; height: 41px !important; cursor:move } -#slider1 .slider-selection { - background: #FFD700; -} -#slider1 .slider-track-high { - background: #FF4500; -} -#slider1 .slider-track-low { - background: #66CD00; -} -table[data-sortable] { - border-collapse: collapse; - border-spacing: 0; -} -table[data-sortable] th { - vertical-align: bottom; - font-weight: bold; -} -table[data-sortable] th, table[data-sortable] td { - text-align: left; - padding: 10px; -} -table[data-sortable] th:not([data-sortable="false"]) { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - -webkit-touch-callout: none; - cursor: pointer; -} -table[data-sortable] th:after { - content: ""; - visibility: hidden; - display: inline-block; - vertical-align: inherit; - height: 0; - width: 0; - border-width: 5px; - border-style: solid; - border-color: transparent; - margin-right: 1px; - margin-left: 10px; - float: right; -} -table[data-sortable] th[data-sortable="false"]:after { - display: none; -} -table[data-sortable] th[data-sorted="true"]:after { - visibility: visible; -} -table[data-sortable] th[data-sorted-direction="descending"]:after { - border-top-color: inherit; - margin-top: 8px; -} -table[data-sortable] th[data-sorted-direction="ascending"]:after { - border-bottom-color: inherit; - margin-top: 3px; -} -table[data-sortable].sortable-theme-bootstrap thead th { - border-bottom: 2px solid #e0e0e0; -} -table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"] { - color: #3a87ad; - background: #d9edf7; - border-bottom-color: #bce8f1; -} -table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"][data-sorted-direction="descending"]:after { - border-top-color: #3a87ad; -} -table[data-sortable].sortable-theme-bootstrap th[data-sorted="true"][data-sorted-direction="ascending"]:after { - border-bottom-color: #3a87ad; -} -table[data-sortable].sortable-theme-bootstrap.sortable-theme-bootstrap-striped tbody > tr:nth-child(odd) > td { - background-color: #f9f9f9; -} -.btn { - text-transform: none; -} -#data td, #no-data td { - vertical-align: middle; -} -.sort-table:hover { - border-bottom-color: #00B7DC !important; -} -.striped:nth-child(odd) { - background-color: #fff; -} -.striped:nth-child(even) { - background-color: #fafafa; - border:1px solid white; -} -.glyphicon-spin { - -webkit-animation: spin 1000ms infinite linear; - animation: spin 1000ms infinite linear; -} -@-webkit-keyframes spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -@keyframes spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(359deg); - transform: rotate(359deg); - } -} -</style> -<?php -if (preg_match("/mailbox.php/i", $_SERVER['REQUEST_URI'])): -?> -<style> -.panel-heading div { - margin-top: -18px; - font-size: 15px; -} -.panel-heading div span { - margin-left:5px; -} -.panel-body { - display: none; -} -.clickable { - cursor: pointer; -} -.progress { - margin-bottom: 0px; -} -</style> -<?php -endif; -?> </head> <body style="padding-top:70px"> <nav class="navbar navbar-default navbar-fixed-top" role="navigation"> diff --git a/data/web/inc/mailbox.inc.php b/data/web/inc/mailbox.inc.php index 2b66ea20..f8c9f6ea 100644 --- a/data/web/inc/mailbox.inc.php +++ b/data/web/inc/mailbox.inc.php @@ -671,9 +671,14 @@ function mailbox_edit_alias_domain($postarray) { } try { - $stmt = $pdo->prepare("UPDATE `alias_domain` SET `alias_domain` = :alias_domain, `active` = :active WHERE `alias_domain` = :alias_domain_now"); + $stmt = $pdo->prepare("UPDATE `alias_domain` SET + `alias_domain` = :alias_domain, + `active` = :active, + `modified` = :modified, + WHERE `alias_domain` = :alias_domain_now"); $stmt->execute(array( ':alias_domain' => $alias_domain, + ':modified' => date('Y-m-d H:i:s'), ':alias_domain_now' => $alias_domain_now, ':active' => $active )); @@ -747,11 +752,16 @@ function mailbox_edit_alias($postarray) { } try { - $stmt = $pdo->prepare("UPDATE `alias` SET `goto` = :goto, `active`= :active WHERE `address` = :address"); + $stmt = $pdo->prepare("UPDATE `alias` SET + `goto` = :goto, + `active`= :active, + `modified` = :modified, + WHERE `address` = :address"); $stmt->execute(array( ':goto' => $goto, ':active' => $active, - ':address' => $address + ':address' => $address, + ':modified' => date('Y-m-d H:i:s'), )); $_SESSION['return'] = array( 'type' => 'success', @@ -903,6 +913,7 @@ function mailbox_edit_domain($postarray) { `active` = :active, `quota` = :quota, `maxquota` = :maxquota, + `modified` = :modified, `mailboxes` = :mailboxes, `aliases` = :aliases, `description` = :description @@ -913,6 +924,7 @@ function mailbox_edit_domain($postarray) { ':active' => $active, ':quota' => $quota, ':maxquota' => $maxquota, + ':modified' => date('Y-m-d H:i:s'), ':mailboxes' => $mailboxes, ':aliases' => $aliases, ':modified' => date('Y-m-d H:i:s'), @@ -1856,9 +1868,13 @@ function mailbox_delete_mailbox($postarray) { unset($goto_exploded[$key]); } $gotos_rebuild = implode(',', $goto_exploded); - $stmt = $pdo->prepare("UPDATE `alias` SET `goto` = :goto WHERE `address` = :address"); + $stmt = $pdo->prepare("UPDATE `alias` SET + `goto` = :goto, + `modified` = :modified, + WHERE `address` = :address"); $stmt->execute(array( ':goto' => $gotos_rebuild, + ':modified' => date('Y-m-d H:i:s'), ':address' => $gotos['address'] )); } diff --git a/data/web/lang/lang.en.php b/data/web/lang/lang.en.php index c7d7415e..26f8824e 100644 --- a/data/web/lang/lang.en.php +++ b/data/web/lang/lang.en.php @@ -146,7 +146,7 @@ $lang['user']['tls_policy_warning'] = '<strong>Warning:</strong> If you decide t $lang['user']['tls_policy'] = 'Encryption policy'; $lang['user']['tls_enforce_in'] = 'Enforce TLS incoming'; $lang['user']['tls_enforce_out'] = 'Enforce TLS outgoing'; -$lang['user']['no_record'] = 'No Record'; +$lang['user']['no_record'] = 'No record'; $lang['user']['misc_settings'] = 'Other profile settings'; $lang['user']['misc_delete_profile'] = 'Other profile settings'; @@ -227,8 +227,8 @@ $lang['mailbox']['msg_num'] = 'Message #'; $lang['mailbox']['remove'] = 'Remove'; $lang['mailbox']['edit'] = 'Edit'; $lang['mailbox']['archive'] = 'Archive'; -$lang['mailbox']['no_record'] = 'No Record for object %s'; -$lang['mailbox']['no_record_single'] = 'No Record'; +$lang['mailbox']['no_record'] = 'No record for object %s'; +$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'; @@ -420,5 +420,5 @@ $lang['admin']['invalid_max_msg_size'] = 'Invalid max. message size'; $lang['admin']['site_not_found'] = 'Cannot locate mailcow site configuration'; $lang['admin']['public_folder_empty'] = 'Public folder name must not be empty'; $lang['admin']['set_rr_failed'] = 'Cannot set Postfix restrictions'; -$lang['admin']['no_record'] = 'No Record'; +$lang['admin']['no_record'] = 'No record'; ?> diff --git a/data/web/user.php b/data/web/user.php index 32542b01..8fe71561 100644 --- a/data/web/user.php +++ b/data/web/user.php @@ -113,33 +113,43 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user <div class="tab-content"> <div role="tabpanel" class="tab-pane active" id="SpamAliases"> <div class="row"> - <div class="col-xs-5"> + <div class="col-xs-6"> <p><b><?=$lang['user']['alias'];?></b></p> </div> - <div class="col-xs-4"> + <div class="col-xs-2"> <p><b><?=$lang['user']['alias_valid_until'];?></b></p> </div> - <div class="col-xs-3"> + <div class="col-xs-2"> <p><b><?=$lang['user']['action'];?></b></p> </div> + </div> <?php $get_time_limited_aliases = get_time_limited_aliases($username); if (!empty($get_time_limited_aliases)): foreach ($get_time_limited_aliases as $row): ?> - <div class="col-xs-5"> - <p><?=htmlspecialchars($row['address']);?></p> - </div> - <div class="col-xs-4"> - <p><?=htmlspecialchars(date($lang['user']['alias_full_date'], $row['validity']));?></p> - </div> - <div class="col-xs-3"> - <form class="form-inline" role="form" method="post"> - <a href="#" onclick="$(this).closest('form').submit()" data-toggle="tooltip" data-placement="left" title="<?=$lang['user']['delete_now'];?>"><span class="glyphicon glyphicon-remove"></span></a> - <input type="hidden" name="trigger_set_time_limited_aliases" value="delete"> - <input type="hidden" name="item" value="<?=htmlspecialchars($row['address']);?>"> - </form> - </div> + <div class="row"> + <div class="col-xs-6"> + <p><?=htmlspecialchars($row['address']);?></p> + </div> + <div class="col-xs-2"> + <p><?=htmlspecialchars(date($lang['user']['alias_full_date'], $row['validity']));?></p> + </div> + <div class="col-xs-1"> + <form class="form-inline" role="form" method="post"> + <a class="text-danger" href="#" onclick="$(this).closest('form').submit()"><span class="glyphicon glyphicon-remove"></span></a> + <input type="hidden" name="set_time_limited_aliases" value="delete"> + <input type="hidden" name="item" value="<?=htmlspecialchars($row['address']);?>"> + </form> + </div> + <div class="col-xs-1"> + <form class="form-inline" role="form" method="post"> + <a href="#" onclick="$(this).closest('form').submit()"><span class="glyphicon glyphicon-time"></span> + 1h</a> + <input type="hidden" name="set_time_limited_aliases" value="extend"> + <input type="hidden" name="item" value="<?=htmlspecialchars($row['address']);?>"> + </form> + </div> + </div> <?php endforeach; else: @@ -150,7 +160,6 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user <?php endif; ?> - </div> <form class="form-horizontal" role="form" method="post"> <div class="form-group"> <div class="col-sm-9"> @@ -161,16 +170,16 @@ if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == 'user <option value="168">1 <?=$lang['user']['week'];?></option> <option value="672">4 <?=$lang['user']['weeks'];?></option> </select> - <button type="submit" id="trigger_set_time_limited_aliases" name="trigger_set_time_limited_aliases" value="generate" class="btn btn-success"><?=$lang['user']['alias_create_random'];?></button> + <button type="submit" name="set_time_limited_aliases" value="generate" class="btn btn-success"><?=$lang['user']['alias_create_random'];?></button> </div> </div> <div class="form-group"> <div class="col-sm-12"> - <button style="border-color:#f5f5f5;background:none;color:red" type="submit" name="trigger_set_time_limited_aliases" value="deleteall" class="btn btn-sm"> + <button type="submit" name="set_time_limited_aliases" value="deleteall" class="btn-danger btn btn-sm"> <span class="glyphicon glyphicon-remove" aria-hidden="true"></span> <?=$lang['user']['alias_remove_all'];?> </button> - <button style="border-color:#f5f5f5;background:none;color:grey" type="submit" name="trigger_set_time_limited_aliases" value="extend" class="btn btn-sm"> - <span class="glyphicon glyphicon-hourglass" aria-hidden="true"></span> <?=$lang['user']['alias_extend_all'];?> + <button type="submit" name="set_time_limited_aliases" value="extendall" class="btn-default btn btn-sm"> + <span class="glyphicon glyphicon-time" aria-hidden="true"></span> <?=$lang['user']['alias_extend_all'];?> </button> </div> </div>