550 lines
24 KiB
Plaintext
550 lines
24 KiB
Plaintext
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<title><%-lang.Superuser%> - <%-lang.Shinobi%></title>
|
|
<% window.libURL = originalURL + global.s.checkCorrectPathEnding(config.webPaths.admin) %>
|
|
<% include blocks/header-meta.ejs %>
|
|
<% include blocks/header-favicon.ejs %>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
|
<meta content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0, shrink-to-fit=no' name='viewport' />
|
|
<!-- Fonts and icons -->
|
|
<link href="<%-window.libURL%>libs/css/montserrat.css" rel="stylesheet" />
|
|
<link href="<%-window.libURL%>libs/css/font-awesome.min.css" rel="stylesheet" />
|
|
<!-- CSS Files -->
|
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/bootstrap4.min.css" />
|
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/main.dash2.css" />
|
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/pnotify.custom.min.css">
|
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/now-ui-kit.css?v=1.1.0" />
|
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.basic.css">
|
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/dash2.forms.css">
|
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/super-page.css" />
|
|
<script src="<%-window.libURL%>libs/js/jquery.min.js"></script>
|
|
<script src="<%-window.libURL%>libs/js/basic.js"></script>
|
|
<script src="<%-window.libURL%>libs/js/jquery.serialize.js"></script>
|
|
<script src="<%-window.libURL%>libs/js/pnotify.custom.min.js"></script>
|
|
<script src="<%-window.libURL%>libs/js/popper.min.js" type="text/javascript"></script>
|
|
<script src="<%-window.libURL%>libs/js/bootstrap4.min.js" type="text/javascript"></script>
|
|
<style>
|
|
.form-group label>div:first-child{width:40%}
|
|
.list-group li .form-group {margin:0}
|
|
a {cursor:pointer}
|
|
</style>
|
|
<% customAutoLoad.superLibsCss.forEach(function(lib){ %>
|
|
<link rel="stylesheet" href="<%-window.libURL%>libs/css/<%-lib%>">
|
|
<% }) %>
|
|
</head>
|
|
|
|
<body class="index-page sidebar-collapse bg-hexagon">
|
|
<!-- Navbar -->
|
|
<nav id="main-nav" class="navbar navbar-expand-lg bg-primary fixed-top" color-on-scroll="400">
|
|
<div class="container">
|
|
<div class="navbar-translate">
|
|
<a tabindex="1" class="navbar-brand logout" style="outline:0" href="/" data-placement="bottom">
|
|
<%-lang.superAdminTitle%>
|
|
</a>
|
|
<button class="navbar-toggler navbar-toggler" type="button" data-toggle="collapse" data-target="#navigation" aria-controls="navigation-index" aria-expanded="false" aria-label="Toggle navigation">
|
|
<span class="navbar-toggler-bar bar1"></span>
|
|
<span class="navbar-toggler-bar bar2"></span>
|
|
<span class="navbar-toggler-bar bar3"></span>
|
|
</button>
|
|
</div>
|
|
<div class="collapse navbar-collapse justify-content-end" id="navigation" data-nav-image="<%-window.libURL%>libs/img/blurred-image-1.jpg">
|
|
<ul class="nav navbar-nav navbar-right">
|
|
<li class="nav-item">
|
|
<a href="javascript:location.href=location.pathname" class="nav-link" class="logout">
|
|
<i class="fa fa-sign-out"></i>
|
|
<p class="d-lg-none d-xl-none"><%-lang.Logout%></p>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
<!-- End Navbar -->
|
|
<div class="wrapper">
|
|
<div class="page-header clear-filter" filter-color="primary">
|
|
<div class="container">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div id="main-card" class="card">
|
|
<ul class="nav nav-tabs nav-tabs-neutral justify-content-center bg-primary" id="tablist" role="tablist">
|
|
<li class="nav-item">
|
|
<a class="nav-link active" data-toggle="tab" href="#accounts" role="tab">Accounts</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-toggle="tab" href="#config" role="tab">Configuration</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-toggle="tab" href="#system" role="tab">Controls and Logs</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" data-toggle="tab" href="#changeSuperPreferences" role="tab">Preferences</a>
|
|
</li>
|
|
</ul>
|
|
<div class="card-body">
|
|
<!-- Tab panes -->
|
|
<div class="tab-content text-center">
|
|
<div class="tab-pane active" id="accounts" role="tabpanel">
|
|
<nav class="navbar navbar-rounded navbar-expand-lg bg-primary">
|
|
<div class="container">
|
|
<div class="collapse navbar-collapse">
|
|
<ul class="navbar-nav">
|
|
<li class="nav-item">
|
|
<a class="nav-link add">
|
|
<p><i class="fa fa-plus-square-o"></i> Add Account</p>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
<table class="table table-striped"></table>
|
|
</div>
|
|
<div class="tab-pane" id="config" role="tabpanel">
|
|
<small class="pull-right msg"></small>
|
|
<nav class="navbar navbar-rounded navbar-expand-lg bg-success">
|
|
<div class="container">
|
|
<div class="collapse navbar-collapse">
|
|
<ul class="navbar-nav">
|
|
<li class="nav-item">
|
|
<a class="nav-link submit">
|
|
<p><i class="fa fa-check"></i> <%-lang.Save%></p>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
<form class="form-group-group red" id="conf_json">
|
|
<small class="pull-right msg"></small>
|
|
<div id="configForHumans"></div>
|
|
<div class="form-group">
|
|
<textarea name="json" style="height:300px;font-family: monospace;" class="form-control"></textarea>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="tab-pane text-left" id="system" role="tabpanel">
|
|
<nav class="navbar navbar-rounded navbar-expand-lg bg-primary">
|
|
<div class="container">
|
|
<div class="collapse navbar-collapse">
|
|
<ul class="navbar-nav">
|
|
<li class="nav-item">
|
|
<a class="nav-link" system="deleteLogs">
|
|
<p><i class="fa fa-trash-o"></i> Clear Logs</p>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" restart="system">
|
|
<p><i class="fa fa-retweet"></i> <%-lang['Restart Core']%></p>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" restart="cron">
|
|
<p><i class="fa fa-retweet"></i> <%-lang['Restart CRON']%></p>
|
|
</a>
|
|
</li>
|
|
<li class="nav-item">
|
|
<a class="nav-link" restart="logs">
|
|
<p><i class="fa fa-retweet"></i> <%-lang['Flush PM2 Logs']%></p>
|
|
</a>
|
|
</li>
|
|
<!--
|
|
<li class="nav-item">
|
|
<a class="nav-link" system="update">
|
|
<p><i class="fa fa-arrow-up"></i> <%-lang['Update']%></p>
|
|
</a>
|
|
</li>
|
|
-->
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
<div id="logs" style="height:400px;overflow:auto">
|
|
<table class="table table-striped"></table>
|
|
</div>
|
|
</div>
|
|
<div class="tab-pane text-left" id="changeSuperPreferences" role="tabpanel">
|
|
<% include blocks/changeSuperPreferences.ejs %>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="temp" style="display:none"></div>
|
|
</body>
|
|
<script>
|
|
var superApiPrefix = "<%=originalURL%><%=config.webPaths.superApiPrefix%>"
|
|
</script>
|
|
<% include blocks/confirm.ejs %>
|
|
<% customAutoLoad.superPageBlocks.forEach(function(block){ %>
|
|
<%- include(block) %>
|
|
<% }) %>
|
|
<script src="<%-window.libURL%>libs/js/pnotify.custom.min.js" type="text/javascript"></script>
|
|
<script><% include ../libs/js/moment.js %></script>
|
|
<script src="<%-window.libURL%>libs/js/livestamp.min.js" type="text/javascript"></script>
|
|
<script src="<%-window.libURL%>libs/js/socket.io.js" type="text/javascript"></script>
|
|
<script src="<%-window.libURL%>libs/js/placeholder.js" type="text/javascript"></script>
|
|
<script src="<%-window.libURL%>libs/js/now-ui-kit.js?v=1.1.0" type="text/javascript"></script>
|
|
<script type="text/javascript">
|
|
var lang = <%- JSON.stringify(lang) || {} %>;
|
|
PNotify.prototype.options.styling = "fontawesome";
|
|
$(document).ready(function() {
|
|
// the body of this function is in assets/js/now-ui-kit.js
|
|
$('#main-card').css('margin-top',$('#main-nav').height() * 2)
|
|
});
|
|
|
|
function scrollToDownload() {
|
|
|
|
if ($('.section-download').length != 0) {
|
|
$("html, body").animate({
|
|
scrollTop: $('.section-download').offset().top
|
|
}, 1000);
|
|
}
|
|
}
|
|
</script>
|
|
|
|
<script>$user=<%-JSON.stringify($user)%></script>
|
|
<script>
|
|
$.ccio={accounts:{}};$.ls=localStorage;
|
|
if(!$user.lang||$user.lang==''){
|
|
$user.lang="<%-config.language%>"
|
|
}
|
|
switch($user.lang){
|
|
case'ar'://Arabic
|
|
case'bn'://Bengali
|
|
$('body').addClass('right-to-left')
|
|
$('.mdl-menu__item').each(function(n,v){
|
|
v=$(v).find('i')
|
|
v.appendTo(v.parent())
|
|
})
|
|
break;
|
|
}
|
|
$.ccio.ws=io(location.origin,{
|
|
path : tool.checkCorrectPathEnding(location.pathname)+'socket.io'
|
|
});
|
|
$.ccio.cx=function(x){return $.ccio.ws.emit('super',x)}
|
|
$.ccio.ws.on('connect',function(d){
|
|
$.ccio.cx({f:'init',mail:$user.mail,pass:$user.pass})
|
|
})
|
|
$.ccio.ws.on('f',function(d){
|
|
switch(d.f){
|
|
case'init_success':
|
|
$user.sessionKey = d.superSessionKey
|
|
break;
|
|
case'log':
|
|
$.ccio.tm(4,d.log,'#logs table')
|
|
break;
|
|
case'save_configuration':
|
|
d.msg = 'Saved, Restart Shinobi to apply changes.'
|
|
break;
|
|
case'save_preferences':
|
|
d.msg = 'Saved Preferences'
|
|
break;
|
|
case'edit_account':
|
|
d.msg='Account Edited';
|
|
$.each(d.form,function(n,v){
|
|
$.ccio.accounts[d.ke][n]=v
|
|
})
|
|
$('[ke="'+d.ke+'"] .mail').text(d.form.mail)
|
|
break;
|
|
case'add_account':
|
|
d.msg='Account Created';
|
|
$.ccio.tm(0,d,'#accounts table')
|
|
$.aN.selected = $.ccio.accounts[d.ke]
|
|
break;
|
|
case'delete_account':
|
|
$('#accounts table tr[ke="'+d.ke+'"]').remove()
|
|
break;
|
|
}
|
|
if(d.msg&&typeof d.msg==='string'){
|
|
new PNotify({text:d.msg,type:'error'})
|
|
}
|
|
})
|
|
|
|
$.ccio.tm=function(x,d,z,k){
|
|
var tmp='';if(!d){d={}};if(!k){k={}};
|
|
if(d.id&&!d.mid){d.mid=d.id;}
|
|
switch(x){
|
|
case 0://account row
|
|
d.detailsJSON=JSON.parse(d.details);
|
|
$.ccio.accounts[d.ke]=d;
|
|
tmp+='<tr ke="'+d.ke+'"><td><b class="mail">'+d.mail+'</b></td><td>'+d.ke+'</td><td><a tabindex="1" class="permission btn btn-xs btn-primary"><i class="fa fa-lock"></i></a></td><td><a tabindex="1" class="delete btn btn-xs btn-danger"><i class="fa fa-trash-o"></i></a></td></tr>';
|
|
break;
|
|
case 4://log row, draw to global and monitor
|
|
if(!d.time){d.time=$.ccio.init('t')}
|
|
tmp+='<tr class="search-row"><td><span title="'+d.time+'" class="livestamp"></span><br><small>'+d.time+'</small><br><small>'+d.mid+'</small></td><td></td><td><pre class="pre-inline">'+$.ccio.init('jsontoblock',JSON.parse(d.info))+'</pre></td></tr>'
|
|
break;
|
|
case 5://config element
|
|
if(d.value instanceof Object){
|
|
tmp += '<div class="form-group config-row" layer="'+d.layer+'">\
|
|
<div><input class="form-control key" type="text" value="'+d.key+'"></div>\
|
|
<ul class="list-group valueObject" style="margin:0">'
|
|
++d.layer
|
|
$.each(d.value,function(key,value){
|
|
tmp += '<li class="list-group-item">'
|
|
tmp += $.ccio.tm(5,{key:key,value:value,layer:d.layer})
|
|
tmp += '</li>'
|
|
})
|
|
tmp += '</ul>'
|
|
tmp += '</div>'
|
|
}else{
|
|
tmp += '<div class="form-group config-row" layer="'+d.layer+'">\
|
|
<label>\
|
|
<div><input class="form-control key" type="text" value="'+d.key+'"></div>\
|
|
<div><input class="form-control value" type="text" value="'+d.value+'"></div>\
|
|
</label>\
|
|
</div>'
|
|
}
|
|
break;
|
|
}
|
|
if(z){
|
|
$(z).prepend(tmp)
|
|
}
|
|
switch(x){
|
|
case 4:
|
|
$.ccio.init('ls')
|
|
break;
|
|
}
|
|
return tmp;
|
|
}
|
|
users=<%-JSON.stringify(users)%>;
|
|
if(users){
|
|
$.each(users,function(n,v){
|
|
$.ccio.tm(0,v,'#accounts table')
|
|
})
|
|
}
|
|
$.ccio.init=function(x,d,z,k){
|
|
if(!k){k={}};k.tmp='';
|
|
switch(x){
|
|
case 'ls'://livestamp all
|
|
g={e:jQuery('.livestamp')};
|
|
g.e.each(function(){g.v=jQuery(this),g.t=g.v.attr('title');if(!g.t){return};g.v.toggleClass('livestamp livestamped').attr('title',$.ccio.init('t',g.t)).livestamp(g.t);})
|
|
return g.e
|
|
break;
|
|
case't'://format time
|
|
if(!d){d=new Date();}
|
|
return moment(d).format('YYYY-MM-DD HH:mm:ss')
|
|
break;
|
|
case'jsontoblock'://draw json as block
|
|
if(d instanceof Object){
|
|
k.tmp+='<ul>'
|
|
$.each(d,function(n,v){
|
|
k.tmp+='<li>';
|
|
k.tmp+='<b>'+n+'</b> : '+$.ccio.init('jsontoblock',v);
|
|
k.tmp+='</li>';
|
|
})
|
|
k.tmp+='</ul>'
|
|
}else{
|
|
k.tmp+='<span>';
|
|
k.tmp+=d;
|
|
k.tmp+='</span>';
|
|
}
|
|
break;
|
|
}
|
|
return k.tmp;
|
|
}
|
|
//logs
|
|
$.logs={e:$('#logs')}
|
|
//config editor
|
|
<%
|
|
var stringedConfig = JSON.stringify(plainConfig)
|
|
%>
|
|
var config = <%- JSON.stringify(plainConfig) || [] %>
|
|
$.conf={e:$('#config')};
|
|
$.conf.f = $.conf.e.find('form')
|
|
$.conf.configForHumans=$('#configForHumans')
|
|
$.conf.draw=$.conf.e.find('[name="json"]')
|
|
$.conf.valid=1;
|
|
$.conf.jsonToFields = function(){
|
|
// var tmp = ''
|
|
// $.each(config,function(key,value){
|
|
// var layer = 0
|
|
// tmp += $.ccio.tm(5,{key:key,value:value,layer:layer})
|
|
// })
|
|
// $.conf.configForHumans.html(tmp)
|
|
}
|
|
$.conf.draw.val(JSON.stringify(<%-stringedConfig%>,null,3))
|
|
$.conf.draw.keyup(function(){
|
|
var msg=''
|
|
var color=''
|
|
try{
|
|
config = $.parseJSON($.conf.draw.val())
|
|
msg = 'Valid JSON'
|
|
color = 'success'
|
|
$.conf.valid = 1
|
|
$.conf.jsonToFields()
|
|
}catch(er){
|
|
msg = 'Not a valid JSON'
|
|
color = 'danger'
|
|
$.conf.valid = 0
|
|
}
|
|
new PNotify({text:msg,type:color})
|
|
})
|
|
$.conf.e.find('.submit').click(function(e){
|
|
$.conf.f.submit()
|
|
})
|
|
$.conf.f.submit(function(e){
|
|
e.preventDefault()
|
|
if($.conf.valid===1){
|
|
$.confirm.e.modal('show');
|
|
$.confirm.title.html('Save Configuration <small>conf.json</small>')
|
|
e.html='<p>This is a change being applied to the configuration file (conf.json). Are you sure you want to do this? You must restart Shinobi for these changes to take effect. <b>The JSON below is what you are about to save.</b></p>'
|
|
e.html+='<pre>'+JSON.stringify($.parseJSON($.conf.draw.val()),null,3)+'</pre>'
|
|
$.confirm.body.html(e.html)
|
|
$.confirm.click({title:'Save',class:'btn-success'},function(){
|
|
$.post('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/system/configure',{
|
|
data: $.conf.draw.val()
|
|
},function(data){
|
|
// console.log(data)
|
|
})
|
|
// $.ccio.cx({f:'system',ff:'configure',data:$.parseJSON($.conf.draw.val())})
|
|
});
|
|
}else{
|
|
new PNotify({text:'Invalid JSON Syntax, Cannot Save.',type:'error'})
|
|
}
|
|
return false;
|
|
})
|
|
$.conf.e.on('keyup','.config-row input',function(){
|
|
var newConfig = {}
|
|
var checkRow = function(v,object){
|
|
var _this = $(v)
|
|
var key = _this.find('.key:first').val()
|
|
var layer = parseInt(_this.attr('layer'))
|
|
var list = _this.find('ul').first()
|
|
var isObject = list.length > 0
|
|
if(isObject){
|
|
if(!object[key]){
|
|
if(isNaN(key) === true){
|
|
object[key] = {}
|
|
}else{
|
|
object[key] = []
|
|
}
|
|
}
|
|
list.find('.config-row[layer="'+(layer+1)+'"]').each(function(n,v){
|
|
checkRow(v,object[key])
|
|
})
|
|
}else{
|
|
var value = _this.find('.value').val()
|
|
switch(value){
|
|
case'true':
|
|
value = true
|
|
break;
|
|
case'false':
|
|
value = false
|
|
break;
|
|
default:
|
|
if(isNaN(value) === false){
|
|
value = parseFloat(value)
|
|
}
|
|
break;
|
|
}
|
|
object[key] = value
|
|
}
|
|
|
|
}
|
|
$.conf.configForHumans.children('.config-row').each(function(n,v){
|
|
checkRow(v,newConfig)
|
|
})
|
|
$.conf.draw.val(JSON.stringify(newConfig,null,3))
|
|
console.log(newConfig)
|
|
})
|
|
$.conf.f.ready(function(){
|
|
$.conf.jsonToFields()
|
|
})
|
|
//sys controls
|
|
$.system={e:$('#system')}
|
|
$.system.e.find('[system]').click(function(e){
|
|
switch($(this).attr('system')){
|
|
case'deleteLogs':
|
|
$.confirm.e.modal('show');
|
|
$.confirm.title.html('Delete Logs <small>'+e.u+'</small>')
|
|
e.html='Do you want to delete these logs? User logs will <b>not</b> be deleted.'
|
|
$.confirm.body.html(e.html)
|
|
$.confirm.click({title:'Delete',class:'btn-danger'},function(){
|
|
// $.ccio.cx({f:'logs',ff:'delete',ke:'$'})
|
|
$.get('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/logs/delete',function(data){
|
|
console.log(data)
|
|
})
|
|
$.logs.e.find('table').empty()
|
|
});
|
|
break;
|
|
case'update':
|
|
$.confirm.e.modal('show')
|
|
$.confirm.title.html('Update Shinobi?')
|
|
$.confirm.body.html('Updating Shinobi means overwriting files. If you have modified any files yourself you should update Shinobi manually.')
|
|
$.confirm.click({title:'Update',class:'btn-danger'},function(){
|
|
// $.ccio.cx({f:'system',ff:'update'})
|
|
$.get('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/system/update',function(data){
|
|
console.log(data)
|
|
})
|
|
})
|
|
break;
|
|
}
|
|
})
|
|
$.system.e.find('[restart]').click(function(e){
|
|
$.confirm.e.modal('show');
|
|
e.html=''
|
|
e.title=''
|
|
e.target=$(this).attr('restart').split(',')
|
|
e.target.forEach(function(v){
|
|
switch(v){
|
|
case'system':
|
|
e.html+='<p>Do you want to restart the core (camera.js)? plugins will not be restarted. They will reconnect when Shinobi is back online.</p>'
|
|
break;
|
|
case'cron':
|
|
e.html+='<p>Do you want to restart the CRON (cron.js)?</p>'
|
|
break;
|
|
case'logs':
|
|
e.html+='<p>Flush PM2 console logs? The logs saved in the database will <b>not</b> be deleted.</p>'
|
|
break;
|
|
}
|
|
})
|
|
$.confirm.title.html('Restart?')
|
|
$.confirm.body.html(e.html)
|
|
$.confirm.click({title:'Restart',class:'btn-danger'},function(){
|
|
// $.ccio.cx({f:'system',ff:'restart',target:e.target})
|
|
$.get('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/system/restart/'+encodeURIComponent(e.target),function(data){
|
|
console.log(data)
|
|
})
|
|
});
|
|
})
|
|
$.changeSuperPreferences = {
|
|
window : $('#changeSuperPreferences')
|
|
}
|
|
$.changeSuperPreferences.form = $.changeSuperPreferences.window.find('form')
|
|
$.changeSuperPreferences.form.find('.submit').click(function(){
|
|
$.changeSuperPreferences.form.submit()
|
|
})
|
|
$.changeSuperPreferences.form.submit(function(e){
|
|
e.preventDefault()
|
|
var formValues = $(this).serializeObject()
|
|
// $.ccio.cx({f:'accounts',ff:'saveSuper',form:formValues})
|
|
$.post('<%=originalURL%><%=config.webPaths.superApiPrefix%>'+$user.sessionKey+'/accounts/saveSettings',{
|
|
data: JSON.stringify(formValues)
|
|
},function(data){
|
|
console.log(data)
|
|
})
|
|
return false
|
|
})
|
|
////
|
|
$(document).ready(function(){
|
|
$.each(<%-JSON.stringify(Logs)%>,function(n,v){
|
|
$.ccio.tm(4,v,'#logs table')
|
|
})
|
|
})
|
|
//
|
|
$('body')
|
|
.on('click','.logout',function(e){
|
|
localStorage.removeItem('ShinobiLogin_'+location.host);location.href='/';
|
|
})
|
|
</script>
|
|
<% include blocks/mainpermissions.ejs %>
|
|
<% customAutoLoad.superLibsJs.forEach(function(lib){ %>
|
|
<script src="<%-window.libURL%>libs/js/<%-lib%>"></script>
|
|
<% }) %>
|
|
</html>
|