[Web] Customize app menu and logo; Fix #671
This commit is contained in:
@@ -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>
|
||||
|
||||
|
180
data/web/inc/functions.customize.inc.php
Normal file
180
data/web/inc/functions.customize.inc.php
Normal 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;
|
||||
}
|
||||
}
|
@@ -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(
|
||||
|
@@ -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>
|
||||
|
@@ -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';
|
||||
|
@@ -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
|
||||
|
@@ -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');
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
Reference in New Issue
Block a user