[Web] Customize app menu and logo; Fix #671
parent
a35bf76154
commit
81775765d8
|
@ -129,6 +129,7 @@ $tfa_data = get_tfa();
|
||||||
<a href="#fwdhosts" class="list-group-item"><?=$lang['admin']['forwarding_hosts'];?></a>
|
<a href="#fwdhosts" class="list-group-item"><?=$lang['admin']['forwarding_hosts'];?></a>
|
||||||
<a href="#f2bparams" class="list-group-item"><?=$lang['admin']['f2b_parameters'];?></a>
|
<a href="#f2bparams" class="list-group-item"><?=$lang['admin']['f2b_parameters'];?></a>
|
||||||
<a href="#relayhosts" class="list-group-item">Relayhosts</a>
|
<a href="#relayhosts" class="list-group-item">Relayhosts</a>
|
||||||
|
<a href="#customize" class="list-group-item"><?=$lang['admin']['customize'];?></a>
|
||||||
<a href="#top" class="list-group-item" style="border-top:1px dashed #dadada">↸ <?=$lang['admin']['to_top'];?></a>
|
<a href="#top" class="list-group-item" style="border-top:1px dashed #dadada">↸ <?=$lang['admin']['to_top'];?></a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -260,9 +261,7 @@ $tfa_data = get_tfa();
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="private_key_file"><?=$lang['admin']['private_key'];?>:</label>
|
<label for="private_key_file"><?=$lang['admin']['private_key'];?>:</label>
|
||||||
<textarea class="form-control" rows="5" name="private_key_file" id="private_key_file" required placeholder="-----BEGIN RSA PRIVATE KEY-----
|
<textarea class="form-control" rows="5" name="private_key_file" id="private_key_file" required placeholder="-----BEGIN RSA KEY-----"></textarea>
|
||||||
XYZ
|
|
||||||
-----END RSA PRIVATE KEY-----"></textarea>
|
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-default" id="add_item" data-id="dkim_import" data-api-url='add/dkim_import' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['import'];?></button>
|
<button class="btn btn-default" id="add_item" data-id="dkim_import" data-api-url='add/dkim_import' data-api-attr='{}' href="#"><span class="glyphicon glyphicon-plus"></span> <?=$lang['admin']['import'];?></button>
|
||||||
</form>
|
</form>
|
||||||
|
@ -376,6 +375,82 @@ XYZ
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<span class="anchor" id="customize"></span>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading"><?=$lang['admin']['customize'];?></div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<legend><?=$lang['admin']['change_logo'];?></legend>
|
||||||
|
<p class="help-block"><?=$lang['admin']['logo_info'];?></p>
|
||||||
|
<form class="form-inline" role="form" method="post" enctype="multipart/form-data">
|
||||||
|
<p>
|
||||||
|
<input type="file" name="main_logo" class="filestyle" data-buttonName="btn-default" data-buttonText="Select" accept="image/gif, image/jpeg, image/pjpeg, image/x-png, image/png, image/svg+xml">
|
||||||
|
<button name="submit_main_logo" type="submit" class="btn btn-success"><span class="glyphicon glyphicon-cloud-upload"></span> <?=$lang['admin']['upload'];?></button>
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
<?php
|
||||||
|
if ($main_logo = customize('get', 'main_logo')):
|
||||||
|
$specs = customize('get', 'main_logo_specs');
|
||||||
|
?>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<div class="thumbnail">
|
||||||
|
<img class="img-thumbnail" src="<?=$main_logo;?>" alt="mailcow logo">
|
||||||
|
<div class="caption">
|
||||||
|
<span class="label label-info"><?=$specs['geometry']['width'];?>x<?=$specs['geometry']['height'];?> px</span>
|
||||||
|
<span class="label label-info"><?=$specs['mimetype'];?></span>
|
||||||
|
<span class="label label-info"><?=$specs['fileSize'];?></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<form class="form-inline" role="form" method="post">
|
||||||
|
<p><button name="reset_main_logo" type="submit" class="btn btn-xs btn-default"><?=$lang['admin']['reset_default'];?></button></p>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
endif;
|
||||||
|
?>
|
||||||
|
<legend><?=$lang['admin']['app_links'];?></legend>
|
||||||
|
<p class="help-block"><?=$lang['admin']['merged_vars_hint'];?></p>
|
||||||
|
<form class="form-inline" data-id="app_links" role="form" method="post">
|
||||||
|
<table class="table table-condensed" style="width:1%;white-space: nowrap;" id="app_link_table">
|
||||||
|
<tr>
|
||||||
|
<th><?=$lang['admin']['app_name'];?></th>
|
||||||
|
<th><?=$lang['admin']['link'];?></th>
|
||||||
|
<th> </th>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
$app_links = customize('get', 'app_links');
|
||||||
|
foreach ($app_links as $row) {
|
||||||
|
foreach ($row as $key => $val):
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><input class="input-sm form-control" data-id="app_links" type="text" name="app" required value="<?=$key;?>"></td>
|
||||||
|
<td><input class="input-sm form-control" data-id="app_links" type="text" name="href" required value="<?=$val;?>"></td>
|
||||||
|
<td><a href="#" role="button" class="btn btn-xs btn-default" type="button"><?=$lang['admin']['remove_row'];?></a></td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
endforeach;
|
||||||
|
}
|
||||||
|
foreach ($MAILCOW_APPS as $app):
|
||||||
|
?>
|
||||||
|
<tr>
|
||||||
|
<td><input class="input-sm form-control" value="<?=htmlspecialchars($app['name']);?>" disabled></td>
|
||||||
|
<td><input class="input-sm form-control" value="<?=htmlspecialchars($app['link']);?>" disabled></td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
<?php
|
||||||
|
endforeach;
|
||||||
|
?>
|
||||||
|
</table>
|
||||||
|
<div class="btn-group">
|
||||||
|
<button class="btn btn-success" id="edit_selected" data-item="admin" data-id="app_links" data-reload="no" data-api-url='edit/app_links' data-api-attr='{}' href="#"><?=$lang['admin']['save'];?></button>
|
||||||
|
<button class="btn btn-default" type="button" id="add_app_link_row"><?=$lang['admin']['add_row'];?></button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -53,3 +53,7 @@ body.modal-open {
|
||||||
top: 65px;
|
top: 65px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
.thumbnail img {
|
||||||
|
min-height:100px;
|
||||||
|
height:100px;
|
||||||
|
}
|
|
@ -101,4 +101,13 @@ legend {
|
||||||
-ms-user-select: none
|
-ms-user-select: none
|
||||||
-o-user-select: none;
|
-o-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
}
|
||||||
|
.navbar .navbar-brand {
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
.navbar .navbar-brand img {
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
.mailcow-logo img {
|
||||||
|
max-width: 250px;
|
||||||
}
|
}
|
|
@ -6,10 +6,14 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/modals/footer.php';
|
||||||
<script src="/js/bootstrap-switch.min.js"></script>
|
<script src="/js/bootstrap-switch.min.js"></script>
|
||||||
<script src="/js/bootstrap-slider.min.js"></script>
|
<script src="/js/bootstrap-slider.min.js"></script>
|
||||||
<script src="/js/bootstrap-select.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/notifications.min.js"></script>
|
||||||
<script src="/js/u2f-api.js"></script>
|
<script src="/js/u2f-api.js"></script>
|
||||||
<script src="/js/api.js"></script>
|
<script src="/js/api.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
$(window).scroll(function() {
|
||||||
|
sessionStorage.scrollTop = $(this).scrollTop();
|
||||||
|
});
|
||||||
// Select language and reopen active URL without POST
|
// Select language and reopen active URL without POST
|
||||||
function setLang(sel) {
|
function setLang(sel) {
|
||||||
$.post( "<?= $_SERVER['REQUEST_URI']; ?>", {lang: sel} );
|
$.post( "<?= $_SERVER['REQUEST_URI']; ?>", {lang: sel} );
|
||||||
|
@ -192,6 +196,9 @@ $(document).ready(function() {
|
||||||
|
|
||||||
// CSRF
|
// CSRF
|
||||||
$('<input type="hidden" value="<?= $_SESSION['CSRF']['TOKEN']; ?>">').attr('id', 'csrf_token').attr('name', 'csrf_token').appendTo('form');
|
$('<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>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -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'];
|
$port1 = (!empty($_data['port1'])) ? $_data['port1'] : $is_now['port1'];
|
||||||
$password1 = (!empty($_data['password1'])) ? $_data['password1'] : $is_now['password1'];
|
$password1 = (!empty($_data['password1'])) ? $_data['password1'] : $is_now['password1'];
|
||||||
$host1 = (!empty($_data['host1'])) ? $_data['host1'] : $is_now['host1'];
|
$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'];
|
$enc1 = (!empty($_data['enc1'])) ? $_data['enc1'] : $is_now['enc1'];
|
||||||
$mins_interval = (!empty($_data['mins_interval'])) ? $_data['mins_interval'] : $is_now['mins_interval'];
|
$mins_interval = (!empty($_data['mins_interval'])) ? $_data['mins_interval'] : $is_now['mins_interval'];
|
||||||
$exclude = (!empty($_data['exclude'])) ? $_data['exclude'] : '';
|
$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 {
|
else {
|
||||||
$_SESSION['return'] = array(
|
$_SESSION['return'] = array(
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
<span class="icon-bar"></span>
|
<span class="icon-bar"></span>
|
||||||
</button>
|
</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>
|
||||||
<div id="navbar" class="navbar-collapse collapse">
|
<div id="navbar" class="navbar-collapse collapse">
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<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>
|
<li title="<?= htmlspecialchars($app['description']); ?>"><a href="<?= htmlspecialchars($app['link']); ?>"><?= htmlspecialchars($app['name']); ?></a></li>
|
||||||
<?php
|
<?php
|
||||||
endforeach;
|
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>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -63,6 +63,7 @@ require_once $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.en.php';
|
||||||
include $_SERVER['DOCUMENT_ROOT'] . '/lang/lang.'.$_SESSION['mailcow_locale'].'.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.inc.php';
|
||||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.mailbox.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.domain_admin.inc.php';
|
||||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.policy.inc.php';
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.policy.inc.php';
|
||||||
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.dkim.inc.php';
|
require_once $_SERVER['DOCUMENT_ROOT'] . '/inc/functions.dkim.inc.php';
|
||||||
|
|
|
@ -53,6 +53,7 @@ if (isset($_SESSION['mailcow_cc_role']) && session_check() === false) {
|
||||||
'msg' => 'Form token invalid or timed out'
|
'msg' => 'Form token invalid or timed out'
|
||||||
);
|
);
|
||||||
$_POST = array();
|
$_POST = array();
|
||||||
|
$_FILES = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle logouts
|
// Handle logouts
|
||||||
|
|
|
@ -63,4 +63,14 @@ if (isset($_SESSION['mailcow_cc_role']) && ($_SESSION['mailcow_cc_role'] == "adm
|
||||||
unset_tfa_key($_POST);
|
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');
|
||||||
|
}
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
|
|
|
@ -23,7 +23,7 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> <?= $lang['login']['login']; ?></div>
|
<div class="panel-heading"><span class="glyphicon glyphicon-user" aria-hidden="true"></span> <?= $lang['login']['login']; ?></div>
|
||||||
<div class="panel-body">
|
<div class="panel-body">
|
||||||
<div class="text-center"><img style="max-width: 250px;" src="/img/cow_mailcow.svg" alt="mailcow"></div>
|
<div class="text-center mailcow-logo"><img src="<?=($main_logo = customize('get', 'main_logo')) ? $main_logo : '/img/cow_mailcow.svg';?>" alt="mailcow"></div>
|
||||||
<legend>mailcow UI</legend>
|
<legend>mailcow UI</legend>
|
||||||
<form method="post" autofill="off">
|
<form method="post" autofill="off">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
@ -72,6 +72,14 @@ $_SESSION['return_to'] = $_SERVER['REQUEST_URI'];
|
||||||
<a href="<?= htmlspecialchars($app['link']); ?>" role="button" title="<?= htmlspecialchars($app['description']); ?>" class="btn btn-lg btn-default"><?= htmlspecialchars($app['name']); ?></a>
|
<a href="<?= htmlspecialchars($app['link']); ?>" role="button" title="<?= htmlspecialchars($app['description']); ?>" class="btn btn-lg btn-default"><?= htmlspecialchars($app['name']); ?></a>
|
||||||
<?php
|
<?php
|
||||||
endforeach;
|
endforeach;
|
||||||
|
$app_links = customize('get', 'app_links');
|
||||||
|
foreach ($app_links as $row) {
|
||||||
|
foreach ($row as $key => $val):
|
||||||
|
?>
|
||||||
|
<a href="<?= htmlspecialchars($val); ?>" role="button" class="btn btn-lg btn-default"><?= htmlspecialchars($key); ?></a>
|
||||||
|
<?php
|
||||||
|
endforeach;
|
||||||
|
}
|
||||||
?>
|
?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -90,7 +90,7 @@ var Base64 = {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
jQuery(function($){
|
jQuery(function($){
|
||||||
// http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery
|
// http://stackoverflow.com/questions/24816/escaping-html-strings-with-jquery
|
||||||
var entityMap = {
|
var entityMap = {
|
||||||
|
@ -730,6 +730,24 @@ jQuery(function($){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function add_table_row(table_id) {
|
||||||
|
var row = $('<tr />');
|
||||||
|
cols = '<td><input class="input-sm form-control" data-id="app_links" type="text" name="app" required></td>';
|
||||||
|
cols += '<td><input class="input-sm form-control" data-id="app_links" type="text" name="href" required></td>';
|
||||||
|
cols += '<td><a href="#" role="button" class="btn btn-xs btn-default" type="button">Remove row</a></td>';
|
||||||
|
row.append(cols);
|
||||||
|
table_id.append(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#app_link_table').on('click', 'tr a', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
$(this).parents('tr').remove();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#add_app_link_row').click(function() {
|
||||||
|
add_table_row($('#app_link_table'));
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
$(window).load(function(){
|
$(window).load(function(){
|
||||||
|
|
|
@ -14,7 +14,7 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
return o;
|
return o;
|
||||||
};
|
};
|
||||||
// Collect values of input fields with name "multi_select" an same data-id to js array multi_data[data-id]
|
// Collect values of input fields with name "multi_select" and same data-id to js array multi_data[data-id]
|
||||||
var multi_data = [];
|
var multi_data = [];
|
||||||
$(document).on('change', 'input[name=multi_select]:checkbox', function() {
|
$(document).on('change', 'input[name=multi_select]:checkbox', function() {
|
||||||
if ($(this).is(':checked') && $(this).data('id')) {
|
if ($(this).is(':checked') && $(this).data('id')) {
|
||||||
|
@ -105,7 +105,8 @@ $(document).ready(function() {
|
||||||
url: '/api/v1/' + api_url,
|
url: '/api/v1/' + api_url,
|
||||||
jsonp: false,
|
jsonp: false,
|
||||||
complete: function(data) {
|
complete: function(data) {
|
||||||
// var reponse = (JSON.parse(data.responseText));
|
var response = (data.responseText);
|
||||||
|
// alert(response);
|
||||||
// console.log(reponse.type);
|
// console.log(reponse.type);
|
||||||
// console.log(reponse.msg);
|
// console.log(reponse.msg);
|
||||||
window.location = window.location.href.split("#")[0];
|
window.location = window.location.href.split("#")[0];
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1795,6 +1795,48 @@ if (isset($_SESSION['mailcow_cc_role']) || isset($_SESSION['pending_mailcow_cc_u
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "app_links":
|
||||||
|
if (isset($_POST['attr'])) {
|
||||||
|
$attr = (array)json_decode($_POST['attr'], true);
|
||||||
|
if (is_array($attr)) {
|
||||||
|
if (customize('edit', 'app_links', $attr) === false) {
|
||||||
|
if (isset($_SESSION['return'])) {
|
||||||
|
echo json_encode($_SESSION['return']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'error',
|
||||||
|
'msg' => 'Edit failed'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (isset($_SESSION['return'])) {
|
||||||
|
echo json_encode($_SESSION['return']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'success',
|
||||||
|
'msg' => 'Task completed'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'error',
|
||||||
|
'msg' => 'Incomplete post data'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
echo json_encode(array(
|
||||||
|
'type' => 'error',
|
||||||
|
'msg' => 'Incomplete post data'
|
||||||
|
));
|
||||||
|
}
|
||||||
|
break;
|
||||||
case "relayhost":
|
case "relayhost":
|
||||||
if (isset($_POST['items']) && isset($_POST['attr'])) {
|
if (isset($_POST['items']) && isset($_POST['attr'])) {
|
||||||
$items = (array)json_decode($_POST['items'], true);
|
$items = (array)json_decode($_POST['items'], true);
|
||||||
|
|
|
@ -512,3 +512,14 @@ $lang['success']['relayhost_removed'] = "Relayhost %s wurde entfernt";
|
||||||
$lang['success']['relayhost_added'] = "Relayhost %s wurde hinzugefügt";
|
$lang['success']['relayhost_added'] = "Relayhost %s wurde hinzugefügt";
|
||||||
$lang['admin']['relay_from'] = "Absenderadresse";
|
$lang['admin']['relay_from'] = "Absenderadresse";
|
||||||
$lang['admin']['relay_run'] = "Test durchführen";
|
$lang['admin']['relay_run'] = "Test durchführen";
|
||||||
|
$lang['admin']['customize'] = "Anpassung";
|
||||||
|
$lang['admin']['change_logo'] = "Logo ändern";
|
||||||
|
$lang['admin']['logo_info'] = "Die hochgeladene Grafik wird für die Navigationsleiste auf eine Höhe von 40px skaliert. Für die Startseite ist eine Skalierung auf eine maximale Breite von 250px programmiert. Eine frei skalierbare Grafik (etwa SVG) wird empfohlen.";
|
||||||
|
$lang['admin']['upload'] = "Hochladen";
|
||||||
|
$lang['admin']['app_links'] = "App Links";
|
||||||
|
$lang['admin']['app_name'] = "App Name";
|
||||||
|
$lang['admin']['link'] = "Link";
|
||||||
|
$lang['admin']['remove_row'] = "Zeile entfernen";
|
||||||
|
$lang['admin']['add_row'] = "Zeile hinzufügen";
|
||||||
|
$lang['admin']['reset_default'] = "Auf Standard zurücksetzen";
|
||||||
|
$lang['admin']['merged_vars_hint'] = 'Ausgegraute Zeilen wurden aus der Datei <code>vars.inc.(local.)php</code> gelesen und können nicht mittels UI verändert werden.';
|
||||||
|
|
|
@ -525,3 +525,15 @@ $lang['success']['relayhost_removed'] = "Relayhost %s has been removed";
|
||||||
$lang['success']['relayhost_added'] = "Relayhost %s has been added";
|
$lang['success']['relayhost_added'] = "Relayhost %s has been added";
|
||||||
$lang['admin']['relay_from'] = '"From:" address';
|
$lang['admin']['relay_from'] = '"From:" address';
|
||||||
$lang['admin']['relay_run'] = "Run test";
|
$lang['admin']['relay_run'] = "Run test";
|
||||||
|
|
||||||
|
$lang['admin']['customize'] = "Customize";
|
||||||
|
$lang['admin']['change_logo'] = "Change logo";
|
||||||
|
$lang['admin']['logo_info'] = "Your image will be scaled to a height of 40px for the top navigation bar and a max. width of 250px for the start page. A scalable graphic is highly recommended.";
|
||||||
|
$lang['admin']['upload'] = "Upload";
|
||||||
|
$lang['admin']['app_links'] = "App links";
|
||||||
|
$lang['admin']['app_name'] = "App name";
|
||||||
|
$lang['admin']['link'] = "Link";
|
||||||
|
$lang['admin']['remove_row'] = "Remove row";
|
||||||
|
$lang['admin']['add_row'] = "Add row";
|
||||||
|
$lang['admin']['reset_default'] = "Reset to default";
|
||||||
|
$lang['admin']['merged_vars_hint'] = 'Greyed out rows were merged from <code>vars.inc.(local.)php</code> and cannot be modified.';
|
||||||
|
|
Loading…
Reference in New Issue