455 lines
18 KiB
HTML
455 lines
18 KiB
HTML
<html>
|
|
<!-- Materialze style -->
|
|
<head>
|
|
<link rel="stylesheet" type="text/css" href="../../css/adapter.css"/>
|
|
<link rel="stylesheet" type="text/css" href="../../lib/css/materialize.css">
|
|
|
|
<script type="text/javascript" src="../../lib/js/jquery-3.2.1.min.js"></script>
|
|
<script type="text/javascript" src="../../socket.io/socket.io.js"></script>
|
|
|
|
<script type="text/javascript" src="../../js/translate.js"></script>
|
|
<script type="text/javascript" src="../../lib/js/materialize.js"></script>
|
|
<script type="text/javascript" src="../../js/adapter-settings.js"></script>
|
|
<script type="text/javascript" src="words.js"></script>
|
|
|
|
<script type="text/javascript">
|
|
|
|
var oldBind;
|
|
var oldSecure;
|
|
var oldPort;
|
|
var BACK_FILE_NAME = 'login-bg.png';
|
|
|
|
function initDropZone() {
|
|
document.getElementById('files').addEventListener('change', handleFileSelect, false);
|
|
|
|
var dropZone = document.getElementById('drop_zone');
|
|
if (dropZone) {
|
|
dropZone.addEventListener('dragover', handleDragOver, false);
|
|
dropZone.addEventListener('drop', handleFileSelect, false);
|
|
dropZone.addEventListener('dragend', function () {
|
|
$(this).css({background: 'white'});
|
|
console.log('dragend');
|
|
return false;
|
|
}, false);
|
|
dropZone.addEventListener('dragstart', function () {
|
|
console.log('dragstart');
|
|
}, false);
|
|
dropZone.addEventListener('dragleave', function () {
|
|
$(this).css({background: 'white'});
|
|
}, false);
|
|
dropZone.addEventListener('dragenter', function () {
|
|
$(this).css({background: 'gray'});
|
|
}, false);
|
|
}
|
|
}
|
|
|
|
function showBackImage() {
|
|
// Read names of files for gong
|
|
socket.emit('readFile', 'admin.' + instance, BACK_FILE_NAME, function (err, file) {
|
|
if (!err && file) {
|
|
var arrayBufferView = new Uint8Array(file);
|
|
var blob = new Blob([arrayBufferView], {type: 'image/png'});
|
|
var urlCreator = window.URL || window.webkitURL;
|
|
var imageUrl = urlCreator.createObjectURL( blob );
|
|
$('#login_image').attr('src', imageUrl).show();
|
|
} else {
|
|
$('#login_image').hide();
|
|
}
|
|
});
|
|
}
|
|
|
|
function uploadFile(file, callback) {
|
|
var reader = new FileReader();
|
|
|
|
// Closure to capture the file information.
|
|
reader.onload = function(e) {
|
|
socket.emit('writeFile', 'admin.' + instance, BACK_FILE_NAME, e.target.result, function () {
|
|
if (callback) callback(BACK_FILE_NAME);
|
|
});
|
|
};
|
|
|
|
// Read in the image file as a data URL.
|
|
reader.readAsArrayBuffer(file);
|
|
}
|
|
|
|
function handleFileSelect(evt) {
|
|
evt.preventDefault();
|
|
var files = evt.target.files || evt.dataTransfer.files; // FileList object
|
|
|
|
$('#drop_indcator').hide();
|
|
|
|
// files is a FileList of File objects. List some properties.
|
|
if (!files.length) return;
|
|
|
|
var f = files[0];
|
|
if (f.size > 5 * 1024 * 1024) {
|
|
showMessage(_('File %s is too big. Maximum 5MB', escape(f.name)));
|
|
$('#files').val('');
|
|
return;
|
|
}
|
|
|
|
uploadFile(f, function (name) {
|
|
$('#files').val('');
|
|
showBackImage();
|
|
});
|
|
}
|
|
|
|
function handleFileSelectDrop(evt) {
|
|
$('#drop_indcator').hide();
|
|
evt.stopPropagation();
|
|
evt.preventDefault();
|
|
|
|
var files = evt.dataTransfer.files; // FileList object.
|
|
|
|
// files is a FileList of File objects. List some properties.
|
|
var output = [];
|
|
for (var i = 0, f; f = files[i]; i++) {
|
|
if (f.size > 1024 * 1024) {
|
|
showMessage(_('File %s is too big. Maximum 1MB', escape(f.name)));
|
|
return;
|
|
}
|
|
console.log(escape(f.name));
|
|
}
|
|
}
|
|
|
|
function handleDragOver(evt) {
|
|
evt.stopPropagation();
|
|
evt.preventDefault();
|
|
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
|
|
$('#drop_indcator').show();
|
|
}
|
|
|
|
function showHideSettings(id) {
|
|
var $secure = $('#secure');
|
|
var $auth = $('#auth');
|
|
|
|
if ($secure.prop('checked')) {
|
|
$('.col-certPublic').show();
|
|
$('.col-certPrivate').show();
|
|
$('.col-certChained').show();
|
|
$('.le-settings').removeClass('disabled');
|
|
if ($('#leEnabled').prop('checked')) {
|
|
$('.le-sub-settings').show();
|
|
if ($('#leUpdate').prop('checked')) {
|
|
$('.le-sub-settings-update').show();
|
|
} else {
|
|
$('.le-sub-settings-update').hide();
|
|
}
|
|
} else {
|
|
$('.le-sub-settings').hide();
|
|
}
|
|
} else {
|
|
$('.col-certPublic').hide();
|
|
$('.col-certPrivate').hide();
|
|
$('.col-certChained').hide();
|
|
$('.le-settings').addClass('disabled');
|
|
}
|
|
if ($auth.prop('checked')) {
|
|
$('.tab-login').removeClass('disabled');
|
|
$('#defaultUser').val('admin');
|
|
$('.col-defaultUser').hide();
|
|
$('.col-ttl').show();
|
|
|
|
if ((id === 'auth' || id === 'secure') && !$secure.prop('checked')) {
|
|
confirmMessage(_('Unsecure_Auth'), _('Warning!'), 'security', [_('Ignore warning'), _('Disable authentication')], function (result) {
|
|
if (result === 1) {
|
|
$('#auth').prop('checked', false).trigger('change');
|
|
showToast(null, _('Authentication was deactivated'));
|
|
}
|
|
});
|
|
}
|
|
} else {
|
|
$('.tab-login').addClass('disabled');
|
|
$('.col-defaultUser').show();
|
|
$('.col-ttl').hide();
|
|
}
|
|
if ($('#loginBackgroundImage').prop('checked')) {
|
|
$('.background').show();
|
|
} else {
|
|
$('.background').hide();
|
|
}
|
|
}
|
|
|
|
// the function loadSettings has to exist ...
|
|
function load(settings, onChange) {
|
|
if (!settings) return;
|
|
|
|
if (!settings.thresholdValue) {
|
|
settings.thresholdValue = 200;
|
|
}
|
|
|
|
getIPs(function (ips) {
|
|
for (var i = 0; i < ips.length; i++) {
|
|
$('#bind').append('<option value="' + ips[i].address + '">' + ips[i].name + '</option>');
|
|
}
|
|
$('#bind.value').val(settings.bind).select();
|
|
});
|
|
|
|
oldBind = settings.bind;
|
|
oldSecure = settings.secure;
|
|
oldPort = settings.port;
|
|
|
|
if (settings.autoUpdate === undefined) settings.autoUpdate = 24;
|
|
if (!settings.lePort) settings.lePort = 80;
|
|
|
|
$('.value').each(function () {
|
|
var key = $(this).attr('id');
|
|
var $value = $('#' + key + '.value');
|
|
if ($value.attr('type') === 'checkbox') {
|
|
$value.prop('checked', settings[key]).on('change', function() {
|
|
showHideSettings($(this).attr('id'));
|
|
onChange();
|
|
});
|
|
} else {
|
|
$value.val(settings[key]).on('change', onChange).on('keyup', function() {
|
|
onChange();
|
|
});
|
|
}
|
|
});
|
|
|
|
onChange(false);
|
|
M.updateTextFields();
|
|
|
|
fillSelectCertificates('#certPublic', 'public', settings.certPublic);
|
|
fillSelectCertificates('#certPrivate', 'private', settings.certPrivate);
|
|
fillSelectCertificates('#certChained', 'chained', settings.certChained);
|
|
fillUsers('#defaultUser', settings.defaultUser);
|
|
|
|
initDropZone();
|
|
showBackImage();
|
|
|
|
showHideSettings();
|
|
|
|
$('#loginBackgroundColorHelper').on('change', function () {
|
|
$('#loginBackgroundColor').val($(this).val());
|
|
});
|
|
|
|
if (settings.loginBackgroundColor) {
|
|
$('#loginBackgroundColorHelper').val(settings.loginBackgroundColor);
|
|
}
|
|
|
|
$('#loginBackgroundColor').on('change', function () {
|
|
$('#loginBackgroundColorHelper').val($(this).val() || 'black');
|
|
});
|
|
}
|
|
|
|
function save(callback) {
|
|
var obj = {};
|
|
$('.value').each(function () {
|
|
var $this = $(this);
|
|
if ($this.attr('type') === 'checkbox') {
|
|
obj[$this.attr('id')] = $this.prop('checked');
|
|
} else {
|
|
obj[$this.attr('id')] = $this.val();
|
|
}
|
|
});
|
|
|
|
if ($('#secure').prop('checked') && (!$('#certPrivate').val() || !$('#certPublic').val())) {
|
|
showMessage(_('Set certificates or load it first in the system settings (right top).'));
|
|
return;
|
|
}
|
|
var isRedirect = false;
|
|
var isHttp = false;
|
|
if (oldBind !== obj.bind) {
|
|
isRedirect = true;
|
|
}
|
|
if (oldSecure !== obj.secure) {
|
|
isHttp = true;
|
|
}
|
|
if (oldPort !== obj.port) {
|
|
isRedirect = true;
|
|
}
|
|
var href = '';
|
|
if (isRedirect || isHttp) {
|
|
href = obj.secure ? 'https://' : 'http://';
|
|
|
|
href += (obj.bind !== '0.0.0.0') ? obj.bind : document.location.hostname;
|
|
href += ':' + obj.port;
|
|
}
|
|
|
|
callback(obj, null, href);
|
|
}
|
|
</script>
|
|
<style>
|
|
.adapter-body {
|
|
overflow: hidden !important;
|
|
}
|
|
#drop_zone {
|
|
border: 2px dashed #bbb;
|
|
-moz-border-radius: 5px;
|
|
-webkit-border-radius: 5px;
|
|
border-radius: 5px;
|
|
padding: 25px;
|
|
text-align: center;
|
|
font-size: 20pt;
|
|
font-weight: bold;
|
|
font-family: 'Arial';
|
|
color: #bbb;
|
|
min-width: 320px;
|
|
min-height: 200px
|
|
}
|
|
|
|
.error {
|
|
border: 2px solid red;
|
|
}
|
|
#login_image {
|
|
width: 320px;
|
|
height: auto;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- you have to put your config page in a div with id adapter-container -->
|
|
<div class="m adapter-container">
|
|
<div class="row">
|
|
<div class="col s12">
|
|
<ul class="tabs">
|
|
<li class="tab col s2"><a href="#tab-main" class="translate active">Main settings</a></li>
|
|
<li class="tab col s2 le-settings"><a href="#tab-le" class="translate">Let's Encrypt SSL</a></li>
|
|
<li class="tab col s2 tab-login"><a href="#tab-login" class="translate">Background</a></li>
|
|
</ul>
|
|
</div>
|
|
<div id="tab-main" class="col s12 page">
|
|
<div class="row">
|
|
<div class="col s6 m4 l2">
|
|
<img src="admin.png" class="logo">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="input-field col s12 m8 l5">
|
|
<select class="value" id="bind"></select>
|
|
<label class="translate" for="bind">IP:</label>
|
|
</div>
|
|
<div class="input-field col s12 m4 l3">
|
|
<input class="value" id="port" size="5" maxlength="5" type="number"/>
|
|
<label class="translate" for="port">Port:</label>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="input-field col s12 m6 l4">
|
|
<input class="value" id="secure" type="checkbox" />
|
|
<label class="translate" for="secure">Secure(HTTPS):</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4 col-certPublic">
|
|
<select id="certPublic" class="value"></select>
|
|
<label class="translate" for="certPublic">Public certificate:</label>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="input-field col s12 m6 l4 col-certPrivate">
|
|
<select id="certPrivate" class="value"></select>
|
|
<label class="translate" for="certPrivate">Private certificate:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4 col-certChained">
|
|
<select id="certChained" class="value"></select>
|
|
<label class="translate" for="certChained">Chained certificate:</label>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="input-field col s12 m6 l4">
|
|
<input class="value" id="auth" type="checkbox" />
|
|
<label class="translate" for="auth">Authentication:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4 col-defaultUser">
|
|
<select class="value" id="defaultUser"></select>
|
|
<label class="translate" for="defaultUser">Run as:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4 col-ttl">
|
|
<input class="value" type="number" id="ttl" />
|
|
<label class="translate" for="ttl">Login timeout(sec):</label>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="input-field col s12 m6 l4">
|
|
<select class="value" id="autoUpdate">
|
|
<option value="0" class="translate">manually</option>
|
|
<option value="12" class="translate">every 12 hours</option>
|
|
<option value="24" class="translate">every day</option>
|
|
<option value="48" class="translate">every 2 days</option>
|
|
<option value="72" class="translate">every 3 days</option>
|
|
<option value="168" class="translate">every week</option>
|
|
<option value="336" class="translate">every 2 weeks</option>
|
|
<option value="720" class="translate">monthly</option>
|
|
</select>
|
|
<label class="translate" for="autoUpdate">Auto update:</label>
|
|
</div>
|
|
<div class="input-field col s12 m6 l4">
|
|
<input class="value" id="thresholdValue" type="number" min="50"/>
|
|
<label class="translate" for="thresholdValue">Events threshold value:</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="tab-le" class="col s12 page">
|
|
<div class="row">
|
|
<div class="col s12">
|
|
<img src="../../img/le.png" class="logo-le">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="input-field col s11">
|
|
<input class="value" id="leEnabled" type="checkbox" data-link="lets-encrypt-certificates"/>
|
|
<label for="leEnabled" class="translate">Use Lets Encrypt certificates:</label>
|
|
</div>
|
|
</div>
|
|
<div class="row le-sub-settings">
|
|
<div class="input-field col s11">
|
|
<input class="value" id="leUpdate" type="checkbox" data-link="lets-encrypt-certificates"/>
|
|
<label for="leUpdate" class="translate">Use this instance for automatic update:</label>
|
|
</div>
|
|
</div>
|
|
<div class="row le-sub-settings le-sub-settings-update">
|
|
<div class="input-field col s11 l4">
|
|
<input class="value" id="lePort" type="number" size="5" maxlength="5" data-link="lets-encrypt-certificates"/>
|
|
<label for="lePort" class="translate">Port to check the domain:</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="tab-login" class="col s12 page">
|
|
<div class="row">
|
|
<div class="col s12 m8 l4">
|
|
<input class="value" id="loginBackgroundColor" type="text"/>
|
|
<label class="translate" for="loginBackgroundColor">Background color of the login screen</label>
|
|
<input id="loginBackgroundColorHelper" type="color"/>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col s12 m4 l4">
|
|
<input class="value" id="loginHideLogo" type="checkbox"/>
|
|
<span class="translate" for="loginHideLogo">Hide logo</span>
|
|
</div>
|
|
<div class="col s12 m4 l4">
|
|
<input class="value" id="loginMotto" type="text"/>
|
|
<label class="translate" for="loginMotto">Own motto</label>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col s12 m4 l4">
|
|
<input class="value" id="loginBackgroundImage" type="checkbox"/>
|
|
<span class="translate" for="loginBackgroundImage">Background image</span>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col s12 m4 l4 file-field input-field background">
|
|
<div class="btn">
|
|
<span class="translate">Upload image</span>
|
|
<input type="file" accept=".png,image/png" id="files" name="files" />
|
|
</div>
|
|
<div class="file-path-wrapper">
|
|
<input class="file-path validate" type="text">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col s12 m4 l4 background">
|
|
<div id="drop_zone">
|
|
<span class="translate">place here</span>
|
|
<img id="login_image" src="" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|