[Web] Customize app menu and logo; Fix #671

This commit is contained in:
André
2017-10-21 10:07:06 +02:00
parent a35bf76154
commit 81775765d8
17 changed files with 407 additions and 10 deletions

View File

@@ -6,10 +6,14 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/modals/footer.php';
<script src="/js/bootstrap-switch.min.js"></script>
<script src="/js/bootstrap-slider.min.js"></script>
<script src="/js/bootstrap-select.min.js"></script>
<script src="/js/bootstrap-filestyle.min.js"></script>
<script src="/js/notifications.min.js"></script>
<script src="/js/u2f-api.js"></script>
<script src="/js/api.js"></script>
<script>
$(window).scroll(function() {
sessionStorage.scrollTop = $(this).scrollTop();
});
// Select language and reopen active URL without POST
function setLang(sel) {
$.post( "<?= $_SERVER['REQUEST_URI']; ?>", {lang: sel} );
@@ -192,6 +196,9 @@ $(document).ready(function() {
// CSRF
$('<input type="hidden" value="<?= $_SESSION['CSRF']['TOKEN']; ?>">').attr('id', 'csrf_token').attr('name', 'csrf_token').appendTo('form');
if (sessionStorage.scrollTop != "undefined") {
$(window).scrollTop(sessionStorage.scrollTop);
}
});
</script>

View File

@@ -0,0 +1,180 @@
<?php
function customize($_action, $_item, $_data = null) {
global $redis;
global $lang;
switch ($_action) {
case 'add':
if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
switch ($_item) {
case 'main_logo':
if (in_array($_data['main_logo']['type'], array('image/gif', 'image/jpeg', 'image/pjpeg', 'image/x-png', 'image/png', 'image/svg+xml'))) {
try {
if (file_exists($_data['main_logo']['tmp_name']) !== true) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'Cannot validate image file: Temporary file not found'
);
return false;
}
$image = new Imagick($_data['main_logo']['tmp_name']);
if ($image->valid() !== true) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'Cannot validate image file'
);
return false;
}
$image->destroy();
}
catch (ImagickException $e) {
$image->destroy();
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'Cannot validate image file'
);
return false;
}
}
else {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'Invalid mime type'
);
return false;
}
try {
$redis->Set('MAIN_LOGO', 'data:' . $_data['main_logo']['type'] . ';base64,' . base64_encode(file_get_contents($_data['main_logo']['tmp_name'])));
}
catch (RedisException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'Redis: '.$e
);
return false;
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => 'File uploaded successfully'
);
break;
}
break;
case 'edit':
if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
switch ($_item) {
case 'app_links':
$apps = (array)$_data['app'];
$links = (array)$_data['href'];
$out = array();
if (count($apps) == count($links)) {;
for ($i = 0; $i < count($apps); $i++) {
$out[] = array($apps[$i] => $links[$i]);
}
try {
$redis->set('APP_LINKS', json_encode($out));
}
catch (RedisException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'Redis: '.$e
);
return false;
}
}
$_SESSION['return'] = array(
'type' => 'success',
'msg' => 'Saved changes to app links'
);
break;
}
break;
case 'delete':
if ($_SESSION['mailcow_cc_role'] != "admin") {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => sprintf($lang['danger']['access_denied'])
);
return false;
}
switch ($_item) {
case 'main_logo':
try {
if ($redis->del('MAIN_LOGO')) {
$_SESSION['return'] = array(
'type' => 'success',
'msg' => 'Reset default logo'
);
return true;
}
}
catch (RedisException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'Redis: '.$e
);
return false;
}
break;
}
break;
case 'get':
switch ($_item) {
case 'app_links':
try {
$app_links = json_decode($redis->get('APP_LINKS'), true);
}
catch (RedisException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'Redis: '.$e
);
return false;
}
return ($app_links) ? $app_links : false;
break;
case 'main_logo':
try {
return $redis->get('MAIN_LOGO');
}
catch (RedisException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'Redis: '.$e
);
return false;
}
break;
case 'main_logo_specs':
try {
$image = new Imagick();
$img_data = explode('base64,', customize('get', 'main_logo'));
if ($img_data[1]) {
$image->readImageBlob(base64_decode($img_data[1]));
}
return $image->identifyImage();
}
catch (ImagickException $e) {
$_SESSION['return'] = array(
'type' => 'danger',
'msg' => 'Error: Imagick exception while reading image'
);
return false;
}
break;
}
break;
}
}

View File

@@ -1291,11 +1291,11 @@ function mailbox($_action, $_type, $_data = null) {
$port1 = (!empty($_data['port1'])) ? $_data['port1'] : $is_now['port1'];
$password1 = (!empty($_data['password1'])) ? $_data['password1'] : $is_now['password1'];
$host1 = (!empty($_data['host1'])) ? $_data['host1'] : $is_now['host1'];
$subfolder2 = (!empty($_data['subfolder2'])) ? $_data['subfolder2'] : '';
$subfolder2 = (isset($_data['subfolder2'])) ? $_data['subfolder2'] : $is_now['subfolder2'];
$enc1 = (!empty($_data['enc1'])) ? $_data['enc1'] : $is_now['enc1'];
$mins_interval = (!empty($_data['mins_interval'])) ? $_data['mins_interval'] : $is_now['mins_interval'];
$exclude = (!empty($_data['exclude'])) ? $_data['exclude'] : '';
$maxage = (!empty($_data['maxage'])) ? $_data['maxage'] : $is_now['maxage'];
$maxage = (isset($_data['maxage']) && $_data['maxage'] != "") ? intval($_data['maxage']) : $is_now['maxage'];
}
else {
$_SESSION['return'] = array(

View File

@@ -39,7 +39,7 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/"><img height="32" alt="mailcow-logo" style="margin-top: -5px;" src="/img/cow_mailcow.svg"></a>
<a class="navbar-brand" href="/"><img alt="mailcow-logo" src="<?=($main_logo = customize('get', 'main_logo')) ? $main_logo : '/img/cow_mailcow.svg';?>"></a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
@@ -102,6 +102,14 @@
<li title="<?= htmlspecialchars($app['description']); ?>"><a href="<?= htmlspecialchars($app['link']); ?>"><?= htmlspecialchars($app['name']); ?></a></li>
<?php
endforeach;
$app_links = customize('get', 'app_links');
foreach ($app_links as $row) {
foreach ($row as $key => $val):
?>
<li><a href="<?= htmlspecialchars($val); ?>"><?= htmlspecialchars($key); ?></a></li>
<?php
endforeach;
}
?>
</ul>
</li>

View File

@@ -63,6 +63,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.en.php';
include $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.'.$_SESSION['mailcow_locale'].'.php';
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.customize.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.domain_admin.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.policy.inc.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.dkim.inc.php';

View File

@@ -53,6 +53,7 @@ if (isset($_SESSION['mailcow_cc_role']) && session_check() === false) {
'msg' => 'Form token invalid or timed out'
);
$_POST = array();
$_FILES = array();
}
// Handle logouts

View File

@@ -63,4 +63,14 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
unset_tfa_key($_POST);
}
}
if (isset($_SESSION['mailcow_cc_role']) && $_SESSION['mailcow_cc_role'] == "admin") {
if (isset($_POST["submit_main_logo"])) {
if ($_FILES['main_logo']['error'] == 0) {
customize('add', 'main_logo', $_FILES);
}
}
if (isset($_POST["reset_main_logo"])) {
customize('delete', 'main_logo');
}
}
?>