mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Feat: Add Admin API (#617)
* Push progress
TODO: rework RESET, probably to main.cpp again
* resetPassword rework
* enable administration restriction
* add short cmd for userdata
* Js apis
* Refactor JsonCB class
* Add userToken Auth
* Feat: Close connection if ext clients when def pw is set
* Feat: Protect db against pw/token tests
* WebUi PW Support (#9)
* Initial WebUi Password Support
* Small changes
* Initial WebUi Password Support
* Small changes
* Basic WebUi Token support
* added "removeStorage", added uiLock, updated login page
* Small improvments
* Small change
* Fix: prevent downgrade of authorization
* Add translation for localAdminAuth
* Feat: Show always save button in led layout
* Revert "Feat: Show always save button in led layout"
This reverts commit caad1dfcde
.
* Feat: Password change link in notification
* Fix: body padding modal overlap
* Feat: Add instance index to response on switch
* prevent schema error
Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com>
* Feat: add pw save
* Feat: callout settings/pw replaced with notification
This commit is contained in:
35
assets/webconfig/content/login.html
Normal file
35
assets/webconfig/content/login.html
Normal file
@@ -0,0 +1,35 @@
|
||||
<div class="container" style="margin:20px auto;max-width:500px;">
|
||||
<center>
|
||||
<div>
|
||||
<div class="panel panel-danger">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">Login</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form>
|
||||
<div class="form-group">
|
||||
<input name="password" class="form-control" type="password" id="password" placeholder="Password" autocomplete="off"/>
|
||||
<input name="show_pw" type="checkbox" id="show_pw"/><label for="show_pw">Show/Hide Password</label>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<button type="submit" class="btn btn-sm btn-success" id="btn_password" onclick="requestAuthorization(document.getElementById('password').value); return false;" disabled><i class="fa fa-fw fa-unlock"></i>Login</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</center>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
removeOverlay();
|
||||
|
||||
$('#password').off().on('input',function(e) {
|
||||
if(e.currentTarget.value.length >= 8)
|
||||
$('#btn_password').removeAttr('disabled');
|
||||
});
|
||||
|
||||
$('#show_pw').off().on('change',function(e) {
|
||||
(e.currentTarget.checked ? $('#password').attr('type', 'text') : $('#password').attr('type', 'password'))
|
||||
});
|
||||
</script>
|
File diff suppressed because it is too large
Load Diff
@@ -76,6 +76,8 @@
|
||||
"dashboard_alert_message_confsave_success" : "Deine Hyperion Konfiguration wurde erfolgreich gespeichert. Deine Änderungen sind somit übernommen.",
|
||||
"dashboard_message_global_setting_t": "Instanzunabhängige Einstellung",
|
||||
"dashboard_message_global_setting": "Die Einstellungen auf dieser Seite sind instanzunabhängig. Änderungen werden global übernommen.",
|
||||
"dashboard_message_default_password_t": "WebUi Standardpasswort gesetzt",
|
||||
"dashboard_message_default_password": "Das Standardpasswort der WebUi ist gesetzt. Wir empfehlen dringend, dieses zu ändern.",
|
||||
"dashboard_active_instance": "Ausgewählte Instanz",
|
||||
"main_menu_dashboard_token": "Dashboard",
|
||||
"main_menu_configuration_token": "Konfiguration",
|
||||
@@ -312,6 +314,8 @@
|
||||
"infoDialog_effconf_created_text": "Der Effekt \"$1\" wurde erfolgreich erstellt!",
|
||||
"InfoDialog_lang_title": "Spracheinstellung",
|
||||
"InfoDialog_lang_text": "Sollte dir die Vorauswahl der automatischen Spracherkennung nicht gefallen, kannst du die Sprache hier manuell festlegen.",
|
||||
"InfoDialog_changePassword_title" : "Ändere Passwort",
|
||||
"InfoDialog_changePassword_success" : "Passwort erfolgreich gespeichert!",
|
||||
"InfoDialog_access_title": "Einstellungsstufe",
|
||||
"InfoDialog_access_text": "Je höher die Stufe je mehr Einstellungen und Funktionen stehen zur Verfügung. Empfohlen ist \"Standard\".",
|
||||
"InfoDialog_nowrite_title": "Fehler beim Schreibzugriff!",
|
||||
@@ -612,6 +616,8 @@
|
||||
"edt_conf_net_apiAuth_expl":"Zwinge alle Anwendungen welche die Hyperion API nutzen sich zu authentifizieren. Aktivieren für höhere Sicherheit, da nun jede neue Anwendung einmalig von dir bestätigt werden muss.",
|
||||
"edt_conf_net_localApiAuth_title" : "Lokale API Authentifizierung",
|
||||
"edt_conf_net_localApiAuth_expl" : "Wenn aktiviert, müssen Verbindungen aus dem Heimnetzwerk mit einem Token authentifiziert werden.",
|
||||
"edt_conf_net_localAdminAuth_title":"Lokale Admin Authentifizierung",
|
||||
"edt_conf_net_localAdminAuth_expl":"Wenn aktiviert, muss der Administrationszugriff aus dem Heimnetzwerk mit einem Passwort authentifiziert werden.",
|
||||
"edt_conf_net_restirctedInternetAccessAPI_title" : "Auf IP's beschränken",
|
||||
"edt_conf_net_restirctedInternetAccessAPI_expl": "Den Zugriff auf die API durch das Internet auf bestimmte IP's beschränken",
|
||||
"edt_conf_js_heading_title": "JSON Server",
|
||||
|
@@ -75,6 +75,8 @@
|
||||
"dashboard_alert_message_confsave_success" : "Your Hyperion configuration has been saved successfully. Your changes are now active.",
|
||||
"dashboard_message_global_setting_t": "Instance independent setting",
|
||||
"dashboard_message_global_setting": "The settings on this page are not depending on a specific instance. Changes will be stored globally for all instances.",
|
||||
"dashboard_message_default_password_t": "WebUi default password is set",
|
||||
"dashboard_message_default_password": "The default password for the WebUi is set. We strongly recommend to change this.",
|
||||
"dashboard_active_instance": "Selected instance",
|
||||
"main_menu_dashboard_token" : "Dashboard",
|
||||
"main_menu_configuration_token" : "Configuration",
|
||||
@@ -312,6 +314,8 @@
|
||||
"InfoDialog_lang_title" : "Language setting",
|
||||
"InfoDialog_lang_text" : "If you don't like the result of the automatic language detection you could overwrite it here.",
|
||||
"InfoDialog_access_title" : "Settings level",
|
||||
"InfoDialog_changePassword_title" : "Change Password",
|
||||
"InfoDialog_changePassword_success" : "Password successfully saved!",
|
||||
"InfoDialog_access_text" : "Depending on settings level you could adjust more options or get access to more features. Recommended is the \"Default\" level.",
|
||||
"InfoDialog_nowrite_title" : "write permission error!",
|
||||
"InfoDialog_nowrite_text" : "Hyperion can't write to your current loaded configuration file. Please repair the file permissions to proceed.",
|
||||
@@ -610,7 +614,9 @@
|
||||
"edt_conf_net_apiAuth_title":"API Authentication",
|
||||
"edt_conf_net_apiAuth_expl":"Enforce all applications that use the Hyperion API to authenticate themself against Hyperion (Exception see \"Local API Authentication\"). Higher security, as you control the access and revoke it at any time.",
|
||||
"edt_conf_net_localApiAuth_title" : "Local API Authentication",
|
||||
"edt_conf_net_localApiAuth_expl" : "When enabled, connections from your home network needs to authenticate themself against Hyperion too.",
|
||||
"edt_conf_net_localApiAuth_expl" : "When enabled, connections from your home network needs to authenticate themself against Hyperion with a token.",
|
||||
"edt_conf_net_localAdminAuth_title":"Local Admin API Authentication",
|
||||
"edt_conf_net_localAdminAuth_expl":"When enabled, administration access from your home network needs a password.",
|
||||
"edt_conf_net_restirctedInternetAccessAPI_title" : "Restrict to IP's",
|
||||
"edt_conf_net_restirctedInternetAccessAPI_expl": "You can restrict the access to the API through the internet to certain IP's.",
|
||||
"edt_conf_js_heading_title" : "JSON Server",
|
||||
|
@@ -92,7 +92,7 @@
|
||||
</div>
|
||||
<!-- /.navbar-header -->
|
||||
|
||||
<ul class="nav navbar-top-links navbar-right">
|
||||
<ul class="nav navbar-top-links navbar-right" id="top-navbar">
|
||||
<!-- Browser built in capture stream - streamer.js -->
|
||||
<li class="dropdown" id="btn_streamer" style="display:none">
|
||||
<!-- Hidden helpers -->
|
||||
@@ -170,8 +170,23 @@
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li class="divider"></li>
|
||||
<li id="btn_changePassword">
|
||||
<a>
|
||||
<div>
|
||||
<i class="fa fa-key fa-fw"></i>
|
||||
<span data-i18n="InfoDialog_changePassword_title"></span>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!-- /.lock-ui -->
|
||||
<li class="dropdown" id="btn_lock_ui" style="display:none">
|
||||
<a>
|
||||
<i class="fa fa-lock fa-fw"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- /.navbar-top-left -->
|
||||
|
||||
@@ -216,12 +231,6 @@
|
||||
<h4 id="dashboard_active_instance_friendly_name"></h4>
|
||||
</div>
|
||||
</div>
|
||||
<div id="hyperion_config_write_success_notify" style="display:none;padding:0 10px;margin:0">
|
||||
<div class="bs-callout bs-callout-success">
|
||||
<h4 data-i18n="dashboard_alert_message_confsave_success_t"></h4>
|
||||
<span data-i18n="dashboard_alert_message_confsave_success"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div id="hyperion_global_setting_notify" style="display:none;padding:0 10px;margin:0">
|
||||
<div class="bs-callout bs-callout-warning">
|
||||
<h4 data-i18n="dashboard_message_global_setting_t"></h4>
|
||||
|
@@ -72,23 +72,88 @@ $(document).ready( function() {
|
||||
|
||||
window.showOptHelp = window.serverConfig.general.showOptHelp;
|
||||
});
|
||||
|
||||
|
||||
$(window.hyperion).on("cmd-config-setconfig", function(event) {
|
||||
if (event.response.success === true) {
|
||||
$('#hyperion_config_write_success_notify').fadeIn().delay(5000).fadeOut();
|
||||
showNotification('success', $.i18n('dashboard_alert_message_confsave_success'), $.i18n('dashboard_alert_message_confsave_success_t'))
|
||||
}
|
||||
});
|
||||
|
||||
$(window.hyperion).one("cmd-authorize-login", function(event) {
|
||||
$("#main-nav").removeAttr('style')
|
||||
$("#top-navbar").removeAttr('style')
|
||||
|
||||
if(window.defaultPasswordIsSet === true)
|
||||
showNotification('warning', $.i18n('dashboard_message_default_password'), $.i18n('dashboard_message_default_password_t'), '<a style="cursor:pointer" onClick="changePassword()"> '+$.i18n('InfoDialog_changePassword_title')+'</a>')
|
||||
else
|
||||
//if logged on and pw != default show option to lock ui
|
||||
$("#btn_lock_ui").removeAttr('style')
|
||||
|
||||
|
||||
if (event.response.hasOwnProperty('info'))
|
||||
setStorage("loginToken", event.response.info.token, true);
|
||||
|
||||
requestServerConfigSchema();
|
||||
});
|
||||
|
||||
$(window.hyperion).on("cmd-authorize-newPassword", function(event) {
|
||||
if (event.response.success === true){
|
||||
showInfoDialog("success",$.i18n('InfoDialog_changePassword_success'));
|
||||
// not necessarily true, but better than nothing
|
||||
window.defaultPasswordIsSet = false;
|
||||
}
|
||||
});
|
||||
|
||||
$(window.hyperion).one("cmd-authorize-newPasswordRequired", function(event) {
|
||||
var loginToken = getStorage("loginToken", true)
|
||||
|
||||
if (event.response.info.newPasswordRequired == true)
|
||||
{
|
||||
window.defaultPasswordIsSet = true;
|
||||
|
||||
if(loginToken)
|
||||
requestTokenAuthorization(loginToken)
|
||||
else
|
||||
requestAuthorization('hyperion');
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#main-nav").attr('style', 'display:none')
|
||||
$("#top-navbar").attr('style', 'display:none')
|
||||
|
||||
if(loginToken)
|
||||
requestTokenAuthorization(loginToken)
|
||||
else
|
||||
loadContentTo("#page-content", "login")
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
$(window.hyperion).one("cmd-authorize-adminRequired", function(event) {
|
||||
//Check if a admin login is required.
|
||||
//If yes: check if default pw is set. If no: go ahead to get server config and render page
|
||||
if (event.response.info.adminRequired === true)
|
||||
requestRequiresDefaultPasswortChange();
|
||||
else
|
||||
requestServerConfigSchema();
|
||||
});
|
||||
|
||||
$(window.hyperion).on("error",function(event){
|
||||
showInfoDialog("error","Error", event.reason);
|
||||
//If we are getting an error "No Authorization" back with a set loginToken we will forward to new Login (Token is expired.
|
||||
//e.g.: hyperiond was started new in the meantime)
|
||||
if (event.reason == "No Authorization" && getStorage("loginToken", true))
|
||||
{
|
||||
removeStorage("loginToken", true);
|
||||
requestRequiresAdminAuth();
|
||||
}
|
||||
else
|
||||
{
|
||||
showInfoDialog("error","Error", event.reason);
|
||||
}
|
||||
});
|
||||
|
||||
$(window.hyperion).on("open",function(event){
|
||||
requestAuthorization();
|
||||
requestRequiresAdminAuth();
|
||||
});
|
||||
|
||||
$(window.hyperion).one("ready", function(event) {
|
||||
@@ -190,3 +255,8 @@ $(function(){
|
||||
$(this).toggleClass('active inactive');
|
||||
});
|
||||
});
|
||||
|
||||
// hotfix body padding when bs modals overlap
|
||||
$(document.body).on('hide.bs.modal,hidden.bs.modal', function () {
|
||||
$('body').css('padding-right','0');
|
||||
});
|
||||
|
@@ -28,6 +28,7 @@ window.wSess = [];
|
||||
window.currentHyperionInstance = 0;
|
||||
window.currentHyperionInstanceName = "?";
|
||||
window.comps = [];
|
||||
window.defaultPasswordIsSet = null;
|
||||
tokenList = {};
|
||||
|
||||
function initRestart()
|
||||
@@ -165,9 +166,30 @@ function sendToHyperion(command, subcommand, msg)
|
||||
// -----------------------------------------------------------
|
||||
// wrapped server commands
|
||||
|
||||
function requestAuthorization()
|
||||
// Test if admin requires authentication
|
||||
function requestRequiresAdminAuth()
|
||||
{
|
||||
sendToHyperion("authorize","login",'"username": "Hyperion", "password": "hyperion"');
|
||||
sendToHyperion("authorize","adminRequired");
|
||||
}
|
||||
// Test if the default password needs to be changed
|
||||
function requestRequiresDefaultPasswortChange()
|
||||
{
|
||||
sendToHyperion("authorize","newPasswordRequired");
|
||||
}
|
||||
// Change password
|
||||
function requestChangePassword(oldPw, newPw)
|
||||
{
|
||||
sendToHyperion("authorize","newPassword",'"password": "'+oldPw+'", "newPassword":"'+newPw+'"');
|
||||
}
|
||||
|
||||
function requestAuthorization(password)
|
||||
{
|
||||
sendToHyperion("authorize","login",'"password": "' + password + '"');
|
||||
}
|
||||
|
||||
function requestTokenAuthorization(token)
|
||||
{
|
||||
sendToHyperion("authorize","login",'"token": "' + token + '"');
|
||||
}
|
||||
|
||||
function requestToken(comment)
|
||||
|
@@ -4,6 +4,26 @@ var availLang = ['en','de','es','it','cs'];
|
||||
var availAccess = ['default','advanced','expert'];
|
||||
//$.i18n.debug = true;
|
||||
|
||||
//Change Password
|
||||
function changePassword(){
|
||||
showInfoDialog('changePassword', $.i18n('InfoDialog_changePassword_title'));
|
||||
|
||||
// fill default pw if default is set
|
||||
if(window.defaultPasswordIsSet)
|
||||
$('#oldPw').val('hyperion')
|
||||
|
||||
$('#id_btn_ok').off().on('click',function() {
|
||||
var oldPw = $('#oldPw').val();
|
||||
var newPw = $('#newPw').val();
|
||||
|
||||
requestChangePassword(oldPw, newPw)
|
||||
});
|
||||
|
||||
$('#newPw, #oldPw').off().on('input',function(e) {
|
||||
($('#oldPw').val().length >= 8 && $('#newPw').val().length >= 8) ? $('#id_btn_ok').attr('disabled', false) : $('#id_btn_ok').attr('disabled', true);
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready( function() {
|
||||
|
||||
//i18n
|
||||
@@ -112,6 +132,17 @@ $(document).ready( function() {
|
||||
$('#id_select').trigger('change');
|
||||
});
|
||||
|
||||
// change pw btn
|
||||
$('#btn_changePassword').off().on('click',function() {
|
||||
changePassword();
|
||||
});
|
||||
|
||||
//Lock Ui
|
||||
$('#btn_lock_ui').off().on('click',function() {
|
||||
removeStorage('loginToken', true);
|
||||
location.replace('/');
|
||||
});
|
||||
|
||||
//hide menu elements
|
||||
if (storedAccess != 'expert')
|
||||
$('#load_webconfig').toggle(false);
|
||||
|
@@ -297,6 +297,15 @@ function showInfoDialog(type,header,message)
|
||||
$('#id_footer_rename').html('<button type="button" id="id_btn_ok" class="btn btn-success" data-dismiss-modal="#modal_dialog_rename" disabled><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_ok')+'</button>');
|
||||
$('#id_footer_rename').append('<button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>');
|
||||
}
|
||||
else if (type == "changePassword")
|
||||
{
|
||||
$('#id_body_rename').html('<i style="margin-bottom:20px" class="fa fa-key modal-icon-edit"><br>');
|
||||
$('#id_body_rename').append('<h4>'+header+'</h4>');
|
||||
$('#id_body_rename').append('<input class="form-control" id="oldPw" placeholder="Old" type="text"> <br />');
|
||||
$('#id_body_rename').append('<input class="form-control" id="newPw" placeholder="New" type="text">');
|
||||
$('#id_footer_rename').html('<button type="button" id="id_btn_ok" class="btn btn-success" data-dismiss-modal="#modal_dialog_rename" disabled><i class="fa fa-fw fa-save"></i>'+$.i18n('general_btn_ok')+'</button>');
|
||||
$('#id_footer_rename').append('<button type="button" class="btn btn-danger" data-dismiss="modal"><i class="fa fa-fw fa-close"></i>'+$.i18n('general_btn_cancel')+'</button>');
|
||||
}
|
||||
else if (type == "checklist")
|
||||
{
|
||||
$('#id_body').html('<img style="margin-bottom:20px" src="img/hyperion/hyperionlogo.png" alt="Redefine ambient light!">');
|
||||
@@ -326,7 +335,7 @@ function showInfoDialog(type,header,message)
|
||||
$('#id_body').append('<select id="id_select" class="form-control" style="margin-top:10px;width:auto;"></select>');
|
||||
|
||||
|
||||
$(type == "renInst" ? "#modal_dialog_rename" : "#modal_dialog").modal({
|
||||
$(type == "renInst" || type == "changePassword" ? "#modal_dialog_rename" : "#modal_dialog").modal({
|
||||
backdrop : "static",
|
||||
keyboard: false,
|
||||
show: true
|
||||
@@ -534,8 +543,9 @@ function hexToRgb(hex) {
|
||||
@param type Valid types are "info","success","warning","danger"
|
||||
@param message The message to show
|
||||
@param title A title (optional)
|
||||
@param addhtml Add custom html to the notification end
|
||||
*/
|
||||
function showNotification(type, message, title="")
|
||||
function showNotification(type, message, title="", addhtml="")
|
||||
{
|
||||
if(title == "")
|
||||
{
|
||||
@@ -564,15 +574,19 @@ function showNotification(type, message, title="")
|
||||
// settings
|
||||
type: type,
|
||||
animate: {
|
||||
enter: 'animated fadeInRight',
|
||||
exit: 'animated fadeOutRight'
|
||||
enter: 'animated fadeInDown',
|
||||
exit: 'animated fadeOutUp'
|
||||
},
|
||||
placement:{
|
||||
align:'center'
|
||||
},
|
||||
mouse_over : 'pause',
|
||||
template: '<div data-notify="container" class="bg-w col-xs-11 col-sm-3 bs-callout bs-callout-{0}" role="alert">' +
|
||||
template: '<div data-notify="container" class="bg-w col-md-6 bs-callout bs-callout-{0}" role="alert">' +
|
||||
'<button type="button" aria-hidden="true" class="close" data-notify="dismiss">×</button>' +
|
||||
'<span data-notify="icon"></span> ' +
|
||||
'<h4 data-notify="title">{1}</h4> ' +
|
||||
'<span data-notify="message">{2}</span>' +
|
||||
addhtml+
|
||||
'<div class="progress" data-notify="progressbar">' +
|
||||
'<div class="progress-bar progress-bar-{0}" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>' +
|
||||
'</div>' +
|
||||
|
Reference in New Issue
Block a user