new front end #33
This commit is contained in:
+207
-109
@@ -1,78 +1,106 @@
|
||||
<%- include('top') %>
|
||||
<script id="rowTemplate" type="text/html">
|
||||
<tr action="api" class="<<fresh>>">
|
||||
<input type="hidden" name="host" value="<< host >>" />
|
||||
<td><a target="_blank" href="<<forcessl>><<host>>"><<forcessl>><<host>></a></td>
|
||||
<td><< targetssl >><< ip >>:<< targetPort >></td>
|
||||
<td class="hidden-xs"><<updated_on>></td>
|
||||
<td>
|
||||
<button type="button" data-host="<< host >>" onclick="editHost(this);" class="btn btn-sm btn-default">Edit</button>
|
||||
<button type="button" onclick="app.host.remove({host:'<<host>>'}, function(){tableAJAX('Host <<host>> delete.')})" class="btn btn-sm btn-default">Delete</button>
|
||||
</td>
|
||||
</tr>
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
var currentEditHost;
|
||||
// Require login to see this page.
|
||||
app.auth.forceLogin()
|
||||
</script>
|
||||
|
||||
<style type="text/css">
|
||||
label.control-label{
|
||||
font-weight: bold;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.card-title{
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
div.editWindow{
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function parseHostRow(host) {
|
||||
host['updated_on_text'] = moment(host['updated_on'], "x").fromNow();
|
||||
host['targetssl_text'] = host['targetssl'] ? 'https://' : 'http://';
|
||||
host['forcessl_text'] = host['forcessl'] ? 'https://' : 'http://';
|
||||
|
||||
return host;
|
||||
}
|
||||
|
||||
function populateHosts(){
|
||||
app.host.list(function(error, res){
|
||||
if(error) return app.util.actionMessage(error, $.scope.hosts.$this, 'danger');
|
||||
|
||||
for(let host of res){
|
||||
$.scope.hosts.push(parseHostRow(host));
|
||||
}
|
||||
|
||||
$.scope.hosts.__setPut(function($el, item, list){
|
||||
$el.addClass('bg-success');
|
||||
$el.fadeIn(1000, function(){
|
||||
$el.removeClass('bg-success');
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function cancleHostEdit(){
|
||||
$('#hostsTable').find('tr').each(function(idx, el){
|
||||
console.log('here?')
|
||||
$(el).removeClass('table-warning');
|
||||
});
|
||||
$('.editWindow').slideUp('fast');
|
||||
}
|
||||
|
||||
function editHost(btn, host){
|
||||
cancleHostEdit();
|
||||
$(btn).closest('tr').addClass('table-warning');
|
||||
$('.editWindow .card-title').html("Edit "+ host);
|
||||
|
||||
$('div.editWindow .card-body span').html($('#addHost').html());
|
||||
$('div.editWindow .card-body span button').remove();
|
||||
|
||||
$(".editWindow input[name='edit_host']").val(host);
|
||||
|
||||
function editHost(btn){
|
||||
var btn = $(btn);
|
||||
currentEditHost = btn.data('host');
|
||||
$('.editWindow').slideDown('fast');
|
||||
$('.editWindow .panel-title .pull-left').html("Edit "+ btn.data('host'))
|
||||
|
||||
$('div.editWindow .panel-body span').html($('#addHost').html())
|
||||
$('div.editWindow .panel-body span button').remove()
|
||||
|
||||
$(".editWindow input[name='edit_host']").val(btn.data('host'));
|
||||
|
||||
app.host.get(currentEditHost, function(error, data){
|
||||
console.log(data)
|
||||
app.host.get(host, function(error, data){
|
||||
$.each( data.results, function( key, value ) {
|
||||
if(typeof value == "boolean"){
|
||||
$(".editWindow #"+ key +"-"+ value).prop('checked', true)
|
||||
}else{
|
||||
$(".editWindow input[name='" + key + "']").val(value);
|
||||
}
|
||||
$('.editWindow .panel-body').slideDown('fast');
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function tableAJAX(actionMessage){
|
||||
|
||||
$('#tableAJAX').html('').hide();
|
||||
app.util.actionMessage('')
|
||||
|
||||
app.host.list(function(err, data){
|
||||
if(err) return app.util.actionMessage(err, {type: 'danger'});
|
||||
if(data){
|
||||
$.each(data, function( key, value ) {
|
||||
value['updated_on'] = moment(value['updated_on'], "x").fromNow();
|
||||
value['targetssl'] = value['targetssl'] ? "https://" : "http://";
|
||||
value['forcessl'] = value['forcessl'] ? "https://" : "http://";
|
||||
host_row = ich.rowTemplate(value);
|
||||
$('#tableAJAX').append(host_row);
|
||||
});
|
||||
app.util.actionMessage(actionMessage || '', {type: 'info'});
|
||||
$('#tableAJAX').fadeIn('slow');
|
||||
}else{
|
||||
app.util.actionMessage('No hosts...', {type: 'info'});
|
||||
}
|
||||
function deleteHost(host){
|
||||
app.host.remove({host: host}, function(err, data){
|
||||
// app.util.actionMessage(`Host ${host} deleted!`, $.scope.hosts.$this, 'danger');
|
||||
$.scope.hosts.remove(host);
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
tableAJAX(); //populate the table
|
||||
setInterval(tableAJAX, 30000);
|
||||
populateHosts(); //populate the table
|
||||
|
||||
$.scope.hosts.__setTake(function($el, item, list){
|
||||
$el.addClass('bg-danger');
|
||||
$el.fadeOut(1000, function(){
|
||||
$el.remove()
|
||||
});
|
||||
});
|
||||
|
||||
$('form.addHost').on('submit', function(){
|
||||
event.preventDefault();
|
||||
|
||||
$form = $(this);
|
||||
|
||||
var action = $($form.find('button[type="submit"]')[0]).data('type')
|
||||
|
||||
app.util.actionMessage('')
|
||||
var action = $($form.find('button[type="submit"]')[0]).data('type');
|
||||
app.util.actionMessage('', $form);
|
||||
|
||||
if($form.attr('isValid') === 'true'){
|
||||
var formdata = $form.serializeObject();
|
||||
@@ -82,15 +110,18 @@
|
||||
|
||||
app.host[action](formdata, function(error, data){
|
||||
if(error){
|
||||
console.log('error data',data)
|
||||
app.util.actionMessage(error + data.message, {type: 'danger'});
|
||||
app.util.actionMessage(error + data.message, $form, 'danger');
|
||||
return;
|
||||
}
|
||||
|
||||
if($.scope.hosts.indexOf(data.__requestedHost) >= 0){
|
||||
$.scope.hosts.update(data.__requestedHost, parseHostRow(data));
|
||||
}else{
|
||||
$.scope.hosts.splice(0,0, parseHostRow(data))
|
||||
}
|
||||
|
||||
if(action == 'edit') $('.editWindow').slideUp('fast');
|
||||
|
||||
app.util.actionMessage(data.message || 'Error!', {type: 'info'});
|
||||
tableAJAX("Added "+ formdata.host);
|
||||
$form.trigger('reset');
|
||||
})
|
||||
}
|
||||
@@ -98,38 +129,61 @@
|
||||
});
|
||||
</script>
|
||||
<div class="row" style="display:none">
|
||||
<div class="col-md-4">
|
||||
<div class="panel panel-danger editWindow" style="display:none">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title">
|
||||
<div class="pull-left">Edit $host!</div>
|
||||
|
||||
<div class="pull-right">
|
||||
<label class="glyphicon glyphicon-circle-arrow-down"></label>
|
||||
<label class="glyphicon glyphicon-remove-circle"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col col-md-12 col-lg-4 col-xl-3 col-xxl-2">
|
||||
<!--
|
||||
left column
|
||||
-->
|
||||
<div class="card shadow-lg editWindow" style="display:none">
|
||||
<!--
|
||||
Edit host card
|
||||
-->
|
||||
<div class="card-header text-center bg-warning">
|
||||
<span class="card-icon float-start">
|
||||
<i class="fa-solid fa-pencil"></i>
|
||||
</span>
|
||||
<span class="card-title">
|
||||
</span>
|
||||
<span class="float-end">
|
||||
<i class="fa-solid fa-circle-minus"></i>
|
||||
<i class="fa-solid fa-circle-xmark" onclick="cancleHostEdit()"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="card-body">
|
||||
<form class="addHost" onsubmit="$(this).validate()">
|
||||
<span></span>
|
||||
<input type="hidden" name="edit_host" />
|
||||
<button type="submit" data-type="edit" class="btn btn-danger host-submit">Update</button>
|
||||
<button class="btn btn-link" type="reset">Cancel</button>
|
||||
<button type="submit" data-type="edit" class="btn btn-warning">
|
||||
<i class="fa-solid fa-pencil"></i>
|
||||
Update
|
||||
</button>
|
||||
<button class="btn btn-secondary" type="reset" onclick="cancleHostEdit()">
|
||||
<i class="fa-solid fa-ban"></i>
|
||||
Cancel
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title">
|
||||
Add New Proxy
|
||||
<div class="pull-right">
|
||||
<label class="glyphicon glyphicon-circle-arrow-down panel-toggle"></label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card shadow-lg">
|
||||
<!--
|
||||
Add new host card
|
||||
-->
|
||||
<div class="card-header text-center">
|
||||
<span class="card-icon float-start">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
</span>
|
||||
<span class="card-title">
|
||||
New Entry
|
||||
</span>
|
||||
<span class="float-end">
|
||||
<i class="fa-solid fa-circle-minus"></i>
|
||||
</span>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
|
||||
<div class="card-header actionMessage" style="display:none"></div>
|
||||
|
||||
<div class="card-body">
|
||||
<form class="addHost" id="addHost" onsubmit="$(this).validate()">
|
||||
|
||||
<div class="form-group">
|
||||
@@ -149,7 +203,7 @@
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label">Hostname</label>
|
||||
<label class="control-label">Incoming Host Name</label>
|
||||
<input type="text" name="host" class="form-control" placeholder="ex: proxy.cloud-ops.net" validate=":3" >
|
||||
</div>
|
||||
|
||||
@@ -178,42 +232,86 @@
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" data-type="add" class="btn btn-default host-submit">Add</button>
|
||||
<hr />
|
||||
<button type="submit" data-type="add" class="btn btn-success">
|
||||
<i class="fa-solid fa-plus"></i>
|
||||
Add
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title">
|
||||
<div class="col col-md-12 col-lg-8 col-xl-9 col-xxl-10">
|
||||
<!--
|
||||
Right column
|
||||
-->
|
||||
<div class="card shadow-lg">
|
||||
<!--
|
||||
List current hosts
|
||||
-->
|
||||
<div class="card-header text-center">
|
||||
<span class="card-icon float-start">
|
||||
<i class="fa-solid fa-network-wired"></i>
|
||||
</span>
|
||||
<span class="card-title">
|
||||
Proxy List
|
||||
<div class="pull-right">
|
||||
<label class="glyphicon glyphicon-circle-arrow-down panel-toggle"></label>
|
||||
<label class="glyphicon glyphicon-refresh"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body" style="padding-bottom:0">
|
||||
<div class="alert alert-warning actionMessage" style="display:none">
|
||||
<!-- Message after AJAX action is preformed -->
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>Hostname</th>
|
||||
<th>target</th>
|
||||
<th class="hidden-xs">Updated</th>
|
||||
<th>Actions</th>
|
||||
</thead>
|
||||
<tbody id="tableAJAX">
|
||||
<!-- ajax loaded table -->
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</span>
|
||||
<span class="float-end">
|
||||
<i class="fa-solid fa-circle-minus"></i>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="card-header actionMessage" style="display:none"></div>
|
||||
|
||||
<table class="card-body table table-striped" style="margin-bottom:0">
|
||||
|
||||
<thead>
|
||||
<th>
|
||||
Host Name
|
||||
</th>
|
||||
<th>
|
||||
target
|
||||
</th>
|
||||
<th class="hidden-xs">
|
||||
Updated
|
||||
</th>
|
||||
<th>
|
||||
Actions
|
||||
</th>
|
||||
</thead>
|
||||
<tbody id="hostsTable">
|
||||
<tr action="api" jq-repeat="hosts" jq-repeat-index='host' style="display:none">
|
||||
<td>
|
||||
<a target="_blank" href="{{ forcessl_text }}{{ host }}">
|
||||
{{{ forcessl_text }}}{{ host }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
{{{ targetssl_text }}}{{ ip }}:{{ targetPort }}
|
||||
</td>
|
||||
<td class="hidden-xs momentFromNow" data-date="{{ updated_on }}">
|
||||
{{ updated_on_text }}
|
||||
</td>
|
||||
<td>
|
||||
<div class="btn-group">
|
||||
<!-- <button type="button" class="btn btn-info">
|
||||
<i class="fa-brands fa-expeditedssl"></i>
|
||||
Cert
|
||||
</button> -->
|
||||
<button type="button" onclick="editHost(this, '{{ host }}');" class="btn btn-sm btn-warning">
|
||||
<i class="fa-solid fa-pencil"></i> Edit
|
||||
</button>
|
||||
<button type="button" onclick="deleteHost('{{ host }}')" class="btn btn-sm btn-danger">
|
||||
<i class="fa-solid fa-trash-can"></i>
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
<% include top %>
|
||||
<% include bottom %>
|
||||
+28
-35
@@ -3,57 +3,50 @@
|
||||
|
||||
app.auth.isLoggedIn(function(error, isLoggedIn){
|
||||
if(isLoggedIn){
|
||||
window.location.href = app.util.getUrlParameter('redirect') || '/';
|
||||
app.auth.logInRedirect();
|
||||
}
|
||||
})
|
||||
|
||||
$(document).ready(function(){
|
||||
$( "form[action='login']" ).submit(function( event ) {
|
||||
event.preventDefault();
|
||||
$form = $(this);
|
||||
app.util.actionMessage('')
|
||||
|
||||
if($form.attr('isValid') !== 'true'){
|
||||
console.log('')
|
||||
return app.util.actionMessage('Please fix the errors bellow!')
|
||||
}
|
||||
|
||||
app.auth.logIn($form.serializeObject(), function(error, data){
|
||||
if(data){
|
||||
app.util.actionMessage('Login successful!');
|
||||
window.location.href = app.util.getUrlParameter('redirect') || '/';
|
||||
|
||||
}else{
|
||||
app.util.actionMessage('Login Failed, please try again');
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div class="row">
|
||||
<div class="row" style="display: none;">
|
||||
<div class="col-md-4">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title">Log in</div>
|
||||
<div class="shadow-lg card">
|
||||
<div class="card-header shadow">
|
||||
Password Log in
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="alert alert-warning actionMessage" style="display:none">
|
||||
</div>
|
||||
<form action="login" onsubmit="$(this).validate()">
|
||||
<div class="card-header shadow actionMessage" style="display:none"></div>
|
||||
<div class="card-body">
|
||||
<form action="auth/login" onsubmit="formAJAX(this)" evalAJAX="
|
||||
app.auth.setToken(data.token);
|
||||
app.auth.logInRedirect();
|
||||
">
|
||||
<input type="hidden" name="redirect" value="<%= redirect %>">
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label">User name</label>
|
||||
<input type="text" name="username" class="form-control" placeholder="User" validate="user:3" />
|
||||
<div class="input-group mb-3 shadow">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" ><i class="fa-solid fa-user-tie"></i></span>
|
||||
</div>
|
||||
<input type="text" name="username" class="form-control" placeholder="jsmith" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label class="control-label">Password</label>
|
||||
<input type="password" name="password" class="form-control" placeholder="Password" validate="password:5" />
|
||||
<div class="input-group mb-3 shadow">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text" ><i class="fa-solid fa-key"></i></span>
|
||||
</div>
|
||||
<input type="password" name="password" class="form-control" placeholder="hunter123!"/>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-default" >Log in</button>
|
||||
|
||||
<button type="submit" class="btn btn-outline-dark"><i class="fa-solid fa-right-to-bracket"></i> Log in</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<%- include('bottom') %>
|
||||
<%- include('bottom') %>
|
||||
|
||||
+83
-34
@@ -1,21 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<html >
|
||||
<head>
|
||||
<title>Proxy - Theta 42</title>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Proxy - Theta 42 <%- title %></title>
|
||||
<!-- CSS are placed here -->
|
||||
<link rel='stylesheet' href='/static/css/bootstrap.min.css' />
|
||||
<link rel="stylesheet" href="/static-modules/bootstrap/dist/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="/static-modules/@fortawesome/fontawesome-free/css/all.min.css">
|
||||
|
||||
<link rel='stylesheet' href='/static/css/styles.css' />
|
||||
<!-- Scripts are placed here -->
|
||||
<script type="text/javascript" src='/static/js/jquery.min.js'></script>
|
||||
<script type="text/javascript" src='/static/js/bootstrap.min.js'></script>
|
||||
<script type="text/javascript" src='/static/js/ICanHaz.js'></script>
|
||||
<!-- <script type="text/javascript" src="/socket.io/socket.io.js"></script> -->
|
||||
<script type="text/javascript" src='/static-modules/jquery/dist/jquery.js'></script>
|
||||
<script type="text/javascript" src='/static-modules/jquery-ui/dist/jquery-ui.min.js'></script>
|
||||
<!-- <script type="text/javascript" src="/static/lib/js/popper-1.16.0.min.js"></script> -->
|
||||
<script type="text/javascript" src="/static-modules/bootstrap/dist/js/bootstrap.min.js"></script>
|
||||
<script type="text/javascript" src="/static-modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<script type="text/javascript" src="/static-modules/@fortawesome/fontawesome-free/js/all.min.js"></script>
|
||||
<script type="text/javascript" src='/static-modules/mustache/mustache.min.js'></script>
|
||||
<script type="text/javascript" src='/static/lib/js/jq-repeat_new.js'></script>
|
||||
<script type="text/javascript" src='/static/lib/js/val.js'></script>
|
||||
<script type="text/javascript" src="/static-modules/moment/moment.js"></script>
|
||||
<script type="text/javascript" src="/static/lib/js/app-base.js"></script>
|
||||
<script type="text/javascript" src="/static/js/app.js"></script>
|
||||
<script type="text/javascript" src="/static/js/val.js"></script>
|
||||
<script type="text/javascript" src="/static/js/moment.js"></script>
|
||||
|
||||
|
||||
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
|
||||
@@ -23,27 +30,69 @@
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<a class="navbar-brand" href="#">Dynamic Proxy</a>
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<body>
|
||||
|
||||
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
|
||||
<a class="navbar-brand" href="#">Dynamic Proxy <%- title %></a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse justify-content-end" id="navbarCollapse">
|
||||
<ul class="navbar-nav top-nav">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link active" href="/hosts"><i class="fa-solid fa-network-wired"></i> Hosts</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/users"><i class="fa-solid fa-users"></i> Users Panel</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/topics"> Topics</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="https://github.com/theta42/proxy" target="_blank">
|
||||
<i class="fa-brands fa-github"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="form-inline mt-2 mt-md-0">
|
||||
<!-- Show the login/logout button -->
|
||||
<a id="cl-login-button" class="btn btn-outline-danger my-2 my-sm-0" onclick="app.auth.forceLogin()" style="display: none;">
|
||||
<i class="fas fa-sign-out"></i>
|
||||
Login
|
||||
</a>
|
||||
|
||||
<button id="cl-logout-button" class="btn btn-outline-danger my-2 my-sm-0" onclick="app.auth.logOut(e => window.location.href='/')" style="display: none;">
|
||||
<i class="fas fa-sign-out"></i>
|
||||
Log Out
|
||||
</button>
|
||||
</div>
|
||||
<div id="navbar-collapse-1" class="collapse navbar-collapse navbar-ex4-collapse">
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li><a href="/hosts">Hosts</a>
|
||||
<li><a href="/users">User Panel</a>
|
||||
<li><a href="/" onclick="app.auth.logOut()">Log out</a>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button> -->
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function(){
|
||||
// window.location.pathname.toLocaleLowerCase()
|
||||
|
||||
// Set the correct link to active in the top nav bar
|
||||
$('.top-nav a').each(function(index){
|
||||
let $this = $(this);
|
||||
$this.removeClass('active');
|
||||
if($this.attr('href').toLocaleLowerCase() === window.location.pathname.toLocaleLowerCase()){
|
||||
$this.addClass('active')
|
||||
}
|
||||
})
|
||||
|
||||
// Set the correct login/logout button
|
||||
app.auth.isLoggedIn(function(error, data){
|
||||
if(data) $('#cl-logout-button').show();
|
||||
else $('#cl-login-button').show();
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<!-- Container -->
|
||||
<div class="container">
|
||||
<div id="spa-shell" class="container-fluid">
|
||||
+104
-82
@@ -1,109 +1,131 @@
|
||||
<%- include('top') %>
|
||||
<script id="rowTemplate" type="text/html">
|
||||
<tr action="user/password/<< username >>" method="put" evalAJAX="$form.trigger('reset')">
|
||||
<td>
|
||||
<< uid >>:<< username >>
|
||||
</td>
|
||||
<td>
|
||||
<input type="hidden" name="username" value="<< username >>" />
|
||||
<div class="col-xs-10 form-group">
|
||||
<label class="control-label"></label>
|
||||
<input type="password" size="15" class="form-control" name="password" placeholder="New password" validate="password:5"/>
|
||||
</div>
|
||||
<style type="text/css">
|
||||
@include color-mode(dark) {
|
||||
// CSS variable overrides here...
|
||||
}
|
||||
label.control-label{
|
||||
font-weight: bold;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
.card-title{
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
|
||||
<button type="button btn-warn" onclick="formAJAX(this)" class="btn btn-sm btn-warn">
|
||||
Change
|
||||
</button>
|
||||
</td>
|
||||
<td>
|
||||
<button type="button" onclick="app.user.remove({username: '<<username>>'}, function(){tableAJAX('username <<username>> delete.')})" class="btn btn-sm btn-danger">
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</script>
|
||||
<script type="text/javascript">
|
||||
|
||||
function tableAJAX(actionMessage){
|
||||
$('#tableAJAX').html('').hide();
|
||||
app.util.actionMessage('Refreshing user list...')
|
||||
|
||||
function populateUsers(actionMessage){
|
||||
app.user.list(function(error, data){
|
||||
$.each( data.results, function(key, value) {
|
||||
if(value.uid+'' && value.uid < 1000) return;
|
||||
user_row = ich.rowTemplate(value);
|
||||
$('#tableAJAX').append(user_row);
|
||||
});
|
||||
|
||||
$('#tableAJAX').fadeIn('slow');
|
||||
|
||||
app.util.actionMessage(actionMessage || '', {type: 'info'});
|
||||
if(error) return app.util.actionMessage(error, $.scope.users.$this, 'danger');
|
||||
for(let user of data.results){
|
||||
$.scope.users.push(user);
|
||||
}
|
||||
$.scope.users.__setPut(function($el, item, list){
|
||||
$el.addClass('bg-success');
|
||||
$el.fadeIn(3000, function(){
|
||||
$el.removeClass('bg-success');
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
function removeUser(username){
|
||||
app.user.remove({username: username}, function(error, data){
|
||||
if(error) return app.util.actionMessage(error, $.scope.users.$this, 'danger');
|
||||
$.scope.users.remove(username);
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function(){
|
||||
tableAJAX(); //populate the table
|
||||
populateUsers(); //populate the table
|
||||
|
||||
$.scope.users.__setTake(function($el, item, list){
|
||||
$el.addClass('bg-danger');
|
||||
$el.fadeOut(1000, function(){
|
||||
$el.remove()
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
<div class="row" style="display:none">
|
||||
<div class="col-md-4">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title">
|
||||
Add new user
|
||||
<div class="pull-right">
|
||||
<label class="glyphicon glyphicon-circle-arrow-down panel-toggle"></label>
|
||||
</div>
|
||||
<div class="card shadow-lg">
|
||||
<div class="card-header">
|
||||
<span class="card-header-icon">
|
||||
<i class="fa-solid fa-user-plus"></i>
|
||||
</span>
|
||||
<span class="card-title mx-auto p-2">
|
||||
Add New User
|
||||
</span>
|
||||
<div class="float-right">
|
||||
<i class="fa-solid fa-circle-minus"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<form action="user/" evalAJAX="$form.trigger('reset')">
|
||||
<input type="hidden" class="form-control" name="delete" value="false" />
|
||||
<div class="form-group">
|
||||
<label class="control-label">User-name</label>
|
||||
<input type="text" class="form-control" name="username" placeholder="Letter, numbers, -, _, . and @ only" validate="user:3" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">Password</label>
|
||||
<input type="password" class="form-control" name="password" placeholder="Atleast 5 char. long" validate="password:5"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">Again</label>
|
||||
<input type="password" class="form-control" name="passwordMatch" placeholder="Retype password" validate="eq:password"/>
|
||||
</div>
|
||||
<button type="button" onclick="formAJAX(this)" class="btn btn-default">Add</button>
|
||||
</form>
|
||||
<div class="card-header actionMessage" style="display:none"></div>
|
||||
<div class="card-body">
|
||||
<form action="user/" evalAJAX="
|
||||
$.scope.users.splice(0, 0, data);
|
||||
">
|
||||
<input type="hidden" class="form-control" name="delete" value="false" />
|
||||
<div class="form-group">
|
||||
<label class="control-label">User-name</label>
|
||||
<input type="text" class="form-control" name="username" placeholder="Letter, numbers, -, _, . and @ only" validate="user:3" />
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">Password</label>
|
||||
<input type="password" class="form-control" name="password" placeholder="Atleast 5 char. long" validate="password:5"/>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label class="control-label">Again</label>
|
||||
<input type="password" class="form-control" name="passwordMatch" placeholder="Retype password" validate="eq:password"/>
|
||||
</div>
|
||||
<button type="button" onclick="formAJAX(this)" class="btn btn-info">Add</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<div class="panel-title">
|
||||
<div class="card shadow-lg">
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<i class="fa-solid fa-users"></i>
|
||||
User List
|
||||
<div class="pull-right">
|
||||
<label class="glyphicon glyphicon-circle-arrow-down panel-toggle"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel-body" style="padding-bottom:0">
|
||||
<div class="alert alert-warning actionMessage" style="display:none">
|
||||
<!-- Message after AJAX action is preformed -->
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th>Name</th>
|
||||
<th>Password</th>
|
||||
<th>Delete</th>
|
||||
</thead>
|
||||
<tbody id="tableAJAX">
|
||||
<!-- ajax loaded table -->
|
||||
</tbody>
|
||||
</table>
|
||||
</span>
|
||||
<div class="float-right">
|
||||
<i class="fa-solid fa-circle-minus"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-header actionMessage" style="display:none"></div>
|
||||
<table class="card-body table table-striped" style="margin-bottom:0">
|
||||
<thead>
|
||||
<th>Name</th>
|
||||
<th>Password</th>
|
||||
<th>Delete</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr jq-repeat="users" jq-repeat-index="username" style="display:none" >
|
||||
<td class="align-middle">
|
||||
{{ username }}
|
||||
</td>
|
||||
<td>
|
||||
|
||||
<form class="input-group" action="user/password/{{ username }}" method="put" onsubmit="formAJAX(this)">
|
||||
<input type="password" name="password" class="form-control" placeholder="Change {{ username }} password" aria-label="Update password">
|
||||
<button class="btn btn-warning" type="submit">Change</button>
|
||||
</form>
|
||||
|
||||
</td>
|
||||
<td class="align-middle">
|
||||
<button type="button" class="btn btn-danger" onclick="removeUser('{{username}}')">
|
||||
<i class="fa-solid fa-user-slash"></i>
|
||||
Delete
|
||||
</button>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user