This commit is contained in:
2021-01-16 23:55:27 -05:00
commit 10d10079aa
8070 changed files with 386150 additions and 0 deletions

3
nodejs/views/bottom.ejs Executable file
View File

@ -0,0 +1,3 @@
</div>
</body>
</html>

View File

@ -0,0 +1,25 @@
module.exports = {
subject: 'Password reset for Theta 42 account',
message: `
<h2> Theta 42 account</h2>
<p>
Hello {{ user.givenName }},
</p>
<p>
You have asked to reset the password for user name <b>{{ user.uid }}</b> . Please
click the link below to complete this request. If this was done in errror,
please ignore this email.
</p>
<p>
{{ link }}
</p>
</p>
Thank you,<br />
Theta 42
</p>
`
};

View File

@ -0,0 +1,24 @@
module.exports = {
subject: 'Validate email for Theta 42 account',
message: `
<h2> Theta 42 account</h2>
<p>
Welcome,
</p>
<p>
We need to verify the provided email address in order to continue. Please
follow the link below to verify this email address:
</p>
<p>
{{ link }}
</p>
</p>
Thank you,<br />
Theta 42
</p>
`
};

View File

@ -0,0 +1,34 @@
module.exports = {
subject: 'Welcome to Theta 42!',
message: `
<p>
Welcome {{user.givenName}},
</p>
<p>
Your new Theta 42 Single sign-on account is ready to use. Here is some
information to get you started.
</p>
<p>
Your username is <b>{{user.uid}}</b>
</p>
<p>
You can manage your account at https://sso.theta42.com
</p>
<p>
You account is ready to be used now, test it by SSHing into the Theta 42
jump host \`ssh {{user.uid}}@718it.biz\`
</p>
<p>
The SSO service is still in beta, so please report any bugs you may find!
You will be notified of new features and services as they become available.
</p>
Thank you,<br />
Theta 42
</p>
`
};

217
nodejs/views/groups.ejs Normal file
View File

@ -0,0 +1,217 @@
<%- include('top') %>
<script id="rowTemplate" type="text/html">
<div id="group-card-{{cn}}" class="card shadow">
<div class="card-header">
<h5>
<i class="fad fa-users-class"></i>
Group: {{ cn }}
</h5>
<ul class="nav nav-tabs card-header-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="group-members-tab-{{cn}}" data-toggle="tab" href="#group-memmbers-{{cn}}" role="tab" aria-controls="member" aria-selected="true">
<i class="fad fa-users"></i>
Members
</a>
</li>
<li class="nav-item">
<a class="nav-link" id="group-admins-tab-{{cn}}" data-toggle="tab" href="#group-admins-{{cn}}" role="tab" aria-controls="admin" aria-selected="false">
<i class="fad fa-users-crown"></i>
Owners
</a>
</li>
<li class="nav-item float-right">
</li>
</ul>
</div>
<div class="card-header actionMessage" style="display:none"></div>
<div class="card-body">
<p>
{{ description }}
</p>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade show active" id="group-memmbers-{{cn}}" role="tabpanel" aria-labelledby="member-tab">
<p>
<ul class="list-group">
{{ #member }}
<li id="group-card-{{cn}}-{{uid}}" class="list-group-item shadow">
<i class="fad fa-user"></i> {{ uid }}
<button type="button" action="group/{{groupCN}}/{{uid}}" method="delete" onclick="formAJAX(this)" evalAJAX="addedUser(data.message, '{{groupCN}}', '{{uid}}', $form)" class="btn btn-sm btn-danger float-right">
<i class="fad fa-user-slash"></i>
</button>
</li>
{{ /member }}
</ul>
</p>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="group_add_member" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fad fa-user-plus"></i>
</button>
<div class="dropdown-menu shadow-lg" aria-labelledby="group_add_member">
{{ #toAdd }}{{#.}}
<a class="dropdown-item" action="group/{{groupCN}}/{{uid}}" method="put" onclick="formAJAX(this)" evalAJAX="addedUser(data.message, '{{groupCN}}', '{{uid}}', $form);">
<i class="fad fa-user"></i> {{uid}}
</a>
{{/.}}{{ /toAdd }}
</div>
</div>
</div>
<div class="tab-pane fade" id="group-admins-{{cn}}" role="tabpanel" aria-labelledby="admin-tab">
<p>
<ul class="list-group">
{{ #owner }}
<li class="list-group-item shadow">
<i class="fad fa-user"></i> {{ uid }}
<button type="button" action="group/owner/{{groupCN}}/{{uid}}" method="delete" onclick="formAJAX(this)" evalAJAX="addedUser(data.message, '{{groupCN}}', '{{uid}}', $form)" class="btn btn-sm btn-danger float-right">
<i class="fad fa-user-slash"></i>
</button>
</li>
{{ /owner }}
</ul>
</p>
<div class="dropdown float-left">
<button class="btn btn-secondary dropdown-toggle" type="button" id="group_add_admin" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="fad fa-user-crown"></i>
</button>
<div class="dropdown-menu shadow-lg" aria-labelledby="group_add_admin">
{{ #toAddOwner }}{{#.}}
<a class="dropdown-item" action="group/owner/{{groupCN}}/{{uid}}" method="put" onclick="formAJAX(this)" evalAJAX="addedUser(data.message, '{{groupCN}}', '{{uid}}', $form)">
<i class="fad fa-user"></i> {{uid}}
</a>
{{/.}}{{ /toAddOwner }}
</div>
</div>
</div>
</div>
</div>
<div class="card-footer">
<div class="float-left">
Created: {{createTimestamp}}<br />
Last Mortified: {{modifyTimestamp}}
</div>
<div class="float-right">
<button type="button" onclick="" class="btn btn-warning btn-lg shadow">
<i class="fad fa-edit"></i>
</button>
<button type="button" onclick="app.group.remove({cn: '{{cn}}'}, function(){tableAJAX('Group {{cn}} deleted.')})" class="btn btn-danger btn-lg">
<i class="fad fa-trash"></i>
</button>
</div>
</div>
</div>
<br/>
</script>
<script type="text/javascript">
var userlist;
function getUserList(callback){
app.user.list(function(error, data){
userlist = data.results;
callback()
});
}
function addedUser(message, group, user, $form){
tableAJAX(null, function(){
app.util.actionMessage(message, $("#group-card-"+group), 'success');
$('a[href="#'+$form.closest('.tab-pane').attr('id')+'"]').tab('show');
setTimeout(function(group){
$("body,html").animate({
scrollTop: $("#group-card-" + group).offset().top
}, 0);
}, 400, group);
});
}
function tableAJAX(actionMessage, callback){
var rowTemplate = $('#rowTemplate').html();
var $target = $('#tableAJAX');
$target.html('').hide();
app.util.actionMessage('Refreshing user list...', $target);
app.group.list(function(error, data){
var out = ''
$.each(data.results, function(key, value) {
value.toAdd = userlist.map(function(user){
if(!value.member.includes(user.dn)) return user;
})
value.toAddOwner = userlist.map(function(user){
if(!value.owner.includes(user.dn)) return user;
})
value.member = value.member.map(function(user){
return {
dn: user,
uid: user.match(/cn=[a-zA-Z0-9\_\-\@\.]+/)[0].replace('cn=', '')
}
})
value.owner = value.owner.map(function(user){
return {
dn: user,
uid: user.match(/cn=[a-zA-Z0-9\_\-\@\.]+/)[0].replace('cn=', '')
}
})
value.createTimestamp = moment(value.createTimestamp, "YYYYMMDDHHmmssZ").fromNow();
value.modifyTimestamp = moment(value.modifyTimestamp, "YYYYMMDDHHmmssZ").fromNow();
value.groupCN = value.cn;
out += Mustache.render(rowTemplate, value);
});
$target.html(out);
$target.fadeIn('slow', ($.isFunction(callback) ? callback: function(){})());
app.util.actionMessage(actionMessage || '', $target, 'info');
});
}
$(document).ready(function(){
getUserList(tableAJAX);
});
</script>
<div class="row" style="display:none">
<div class="col-md-4">
<div class="card shadow-lg">
<div class="card-header">
<i class="fas fa-layer-plus"></i>
Add new group
</div>
<div class="card-header actionMessage" style="display:none"></div>
<div class="card-body">
<form action="group/" method="post" onsubmit="formAJAX(this)" evalAJAX="tableAJAX('')">
<div class="form-group">
<label class="control-label">Name</label>
<input type="text" class="form-control shadow" name="name" placeholder="app_gitea_admin" validate=":3" />
</div>
<div class="form-group">
<label class="control-label">Description</label>
<textarea class="form-control shadow" name="description" placeholder="Admin group for gitea app" validate=":3"></textarea>
</div>
<button type="submit" class="btn btn-outline-dark">Add</button>
</form>
</div>
</div>
</div>
<div class="col-md-8" id="tableAJAX">
</div>
</div>
<%- include('bottom') %>

337
nodejs/views/home.ejs Normal file
View File

@ -0,0 +1,337 @@
<%- include('top') %>
<script id="profileTemplate" type="text/html">
<div class="card-body profile-body-{{uid}}">
<h2><i>User Name:</i> <b>{{uid}}</b></h2>
<i>Name:</i> <b>{{givenName}} {{sn}}</b><br />
<i>Email:</i> <b>{{mail}} </b><br />
<i>Phone:</i> <b>{{mobile}} </b><br />
<i>LDAP DN:</i> <b>{{dn}} </b><br />
<i>Home Directory:</i> <b>{{homeDirectory}} </b><br />
<i>Login Shell:</i> <b>{{loginShell}} </b><br />
<i>SSH Public Key:</i> <b>{{sshPublicKey}}</b><br />
<i>Unix User ID:</i> <b>{{uidNumber}} </b><br />
<i>Unix Group ID:</i> <b>{{gidNumber}} </b><br />
<i>Description:</i><br>
<p>
{{description}}
</p>
<!-- <img id="profile_photo" /> -->
</div>
<div class="card-footer profile-body-{{uid}}">
<div class="float-left">
<i>Joined:</i> <b>{{createTimestamp}} </b> <br/>
<i>Edited:</i> <b>{{modifyTimestamp}} </b>
</div>
<div class="float-right">
<button type="button" onclick="editUser()" class="btn btn-warning btn shadow ">
<i class="fad fa-user-edit"></i>
</button>
<button type="submit" class="btn btn btn-danger" action="user/{{uid}}" method="delete" onsubmit="formAJAX(this)" evalAJAX="window.location.href = '/users'">
<i class="fad fa-user-slash"></i>
</button>
</div>
</div>
</script>
<script id="groupRowTemplate" type="text/html">
<tr>
<td>{{cn}}</td>
<td>{{description}}</td>
</tr>
</script>
<script id="userEditTemplate" type="text/html">
<h3>Editing {{uid}}</h3>
<form action="user/{{uid}}" method="put" onsubmit="formAJAX(this)" evalAJAX="editUserSeccess(data.message)">
<div class="form-group">
<label class="control-label">SSH Public Key</label>
<input type="text" class="form-control" name="sshPublicKey" placeholder="ssh-rsa AAAAB3NzaC1yc2EAAAADAQ..." value="{{sshPublicKey}}" />
</div>
<div class="form-group">
<label class="control-label">Mobile Phone</label>
<input type="text" class="form-control" name="mobile" placeholder="9175551234" validate=":9" value="{{mobile}}" />
</div>
<div class="form-group">
<label class="control-label">User Description (Optional)</label>
<textarea class="form-control" name="description" placeholder="Admin group for gitea app">{{description}}</textarea>
</div>
<button type="submit" class="btn btn-outline-dark btn-warning">Change</button>
</form>
</script>
<script id="paswordResetTemplate" type="text/html">
<h3>
Reset Password for {{uid}}
</h3>
<form action="user/{{uid}}/password" method="put" onsubmit="formAJAX(this)" class="form-group">
<div class="form-group">
<label class="control-label">Password</label>
<div class="input-group mb-3 shadow">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-key"></i></span>
</div>
<input type="password" name="userPassword" class="form-control" placeholder="hunter123!" validate=":3" />
</div>
</div>
<div class="form-group">
<label class="control-label">Again</label>
<div class="input-group mb-3 shadow">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-key"></i></span>
</div>
<input type="password" name="password" class="form-control" placeholder="hunter123!" validate="eq:userPassword" />
</div>
</div>
<button type="submit" class="btn btn-outline-secondary shadow">Change</button>
</form>
</script>
<script type="text/javascript">
var currentUser;
function getInvite(){
app.user.createInvite(function(error, data){
$('#invite_token').html(location.origin+"/login/invite/"+data.token);
});
}
function renderProfile(user, message){
var profileTemplate = $('#profileTemplate').html();
var paswordResetTemplate = $('#paswordResetTemplate').html();
var $target = $('#userProfile div.actionMessage');
$('.profile-body-'+user.uid).remove();
app.util.actionMessage(message, $target, 'success')
// data.photo = unescape(encodeURIComponent(data.jpegPhoto));
user.createTimestamp = moment(user.createTimestamp, "YYYYMMDDHHmmssZ").fromNow();
user.modifyTimestamp = moment(user.modifyTimestamp, "YYYYMMDDHHmmssZ").fromNow();
$target.after(Mustache.render(profileTemplate, user));
$('#passwordReset').html(Mustache.render(paswordResetTemplate, user))
};
function renderUserGroups(user){
app.api.get('group/?detail=true&member='+user.uid, function(error, data){
var groupRowTemplate = $('#groupRowTemplate').html();
var $target = $('#mygroups');
$target.html('')
if(error){
app.util.actionMessage(data.message, $target, 'danger');
}else{
for(var group of data.results){
$target.append(Mustache.render(groupRowTemplate, group));
}
}
});
}
function determinUser(callback){
if(location.pathname.includes('/users/')){
var uid = location.pathname.replace('/users/', '');
app.api.get('user/'+uid, function(err, res){
callback(res.results)
})
}else{
callback(app.auth.user)
}
}
function editUser(){
determinUser(function(user){
var $profileCard = $('#userProfile');
var $editCard = $('#editProfile');
var userEditTemplate = $('#userEditTemplate').html()
$editCard.find('.card-body').html(Mustache.render(userEditTemplate, user))
$profileCard.slideUp();
$editCard.slideDown();
});
}
function editUserSeccess(message){
console.log('edit done')
$('#editProfile').slideUp();
app.auth.isLoggedIn(function(){
determinUser(function(user){
currentUser = user;
app.auth.user = user;
renderProfile(user, message);
renderUserGroups(user);
$('#userProfile').slideDown();
});
});
}
$(document).ready(function(){
determinUser(function(user){
currentUser = user;
renderProfile(user);
renderUserGroups(user);
$('#username').text(user.uid);
$('form[action="user/{{uid}}"]').attr('action', 'user/'+user.uid)
});
});
</script>
<style type="text/css">
.services-list i{
padding-right: .5em;
}
</style>
<div class="row" style="display:none">
<div class="col-md-4">
<div class="shadow-lg card mb-3 card-default">
<div class="card-header shadow">
<i class="fas fa-user-plus"></i>
Invite User
<div class="float-right">
<i class="far fa-arrows-v"></i>
</div>
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<button onclick="getInvite(this)" class="btn btn-outline-dark shadow">New Invite Token</button>
<div>
<b id="invite_token"></b>
</div>
</div>
</div>
<div class="shadow-lg card mb-3 card-default">
<div class="card-header shadow">
<div class="float-right">
<i class="far fa-arrows-v"></i>
</div>
<i class="fad fa-th-list"></i>
Services
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<ul class="list-group text-dark services-list">
<li class="list-group-item text-dark">
<i class="fad fa-terminal"></i>
SSH <b id="username"></b>@718it.biz:22
</li>
<a href="https://emby.718it.biz/" target="_blank" class="text-dark">
<li class="list-group-item text-dark">
<i class="fad fa-film"></i>
Emby
</li>
</a>
<a href="https://git.theta42.com" target="_blank" class="text-dark">
<li class="list-group-item text-dark">
<i class="fab fa-git"></i>
Git server
</li>
</a>
<a href="https://rdp.vm42.us" target="_blank" class="text-dark">
<li class="list-group-item text-dark">
<i class="fad fa-desktop"></i>
Virtual Desktops
</li>
</a>
<a href="https://pve.admin.vm42.us" target="_blank" class="text-dark">
<li class="list-group-item text-dark">
<i class="fad fa-server"></i>
Promox (contact wmanlty for access)
</li>
</a>
</ul>
</div>
</div>
<div class="shadow-lg card">
<div class="card-header shadow">
<i class="fad fa-undo-alt"></i>
Password Reset
<div class="float-right">
<i class="far fa-arrows-v"></i>
</div>
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div id="passwordReset" class="card-body">
</div>
</div>
</div>
<div class="col-md-8">
<div id="userProfile" class="shadow-lg card card-default mb-8">
<div class="card-header shadow">
<i class="fad fa-id-card"></i>
Profile
<div class="float-right">
<i class="far fa-arrows-v"></i>
</div>
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="profile-body">
</div>
</div>
<div id="editProfile" class="shadow-lg card card-default mb-8" style="display:none">
<div class="card-header shadow">
<i class="fad fa-id-card"></i>
Edit Profile
<div class="float-right">
<i class="far fa-arrows-v"></i>
</div>
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<div id="tableAJAX">
</div>
</div>
</div>
<br />
<div class="shadow-lg card card-default mb-8">
<div class="card-header shadow">
<i class="fad fa-id-card"></i>
My groups
<div class="float-right">
<i class="far fa-arrows-v"></i>
</div>
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body" style="padding-bottom:0">
<div class="table-responsive">
<table class="table">
<thead>
<th>
Name
</th>
<th>
Description
</th>
</thead>
<tbody id="mygroups">
</tbody>
</table>
</div>
</div>
</div>
<br />
</div>
</div>
<%- include('bottom') %>

2
nodejs/views/index.ejs Executable file
View File

@ -0,0 +1,2 @@
<% include top %>
<% include bottom %>

39
nodejs/views/invite.ejs Normal file
View File

@ -0,0 +1,39 @@
<%- include('top') %>
<script type="text/javascript">
function tableAJAX(message){
app.util.actionMessage(message);
}
$(document).ready(function(){
$('form').attr('action', 'auth/invite/<%= invite.token %>/<%= invite.mail_token %>').attr('evalAJAX', 'location.replace("/login");')
$('[name="mail"').val('<%= invite.mail %>').prop("disabled", true);
});
</script>
<style type="text/css">
div.form-group:hover {
-ms-transform: scale(1.02);
-webkit-transform: scale(1.02);
transform: scale(1.02);
}
</style>
<div class="row" style="display:none">
<div class="col-md-12">
<div class="card shadow-lg">
<div class="card-header">
Add new user
</div>
<div class="card-header actionMessage" style="display:none">
</div>
<div class="card-body">
<p>
Invited By: <b><%= invite.created_by %></b>, <%= invite.created_on %>
</p>
<%- include('user_form') %>
</div>
</div>
</div>
</div>
<%- include('bottom') %>

View File

@ -0,0 +1,59 @@
<%- include('top') %>
<script type="text/javascript">
var emailSent = function(){
$('#email_card .card-body').html("<h1>Thank you!</h1><p>Check your mail</p>")
}
$(document).ready(function(){
});
</script>
<style type="text/css">
div.form-group:hover {
-ms-transform: scale(1.02);
-webkit-transform: scale(1.02);
transform: scale(1.02);
}
</style>
<div class="row">
<div id="email_card" class="card-deck">
<div class="shadow-lg card mb-3">
<div class="card-header">
Validate Email
</div>
<div class="card-header actionMessage" style="display:none">
</div>
<div class="card-body">
<p>
Invited By: <b><%= invite.created_by %></b>, <%= invite.created_on %>.
</p>
<p>
Please enter a valid email address. A link will be sent to
the supplied address to complete the registration process.
</p>
<p>
The supplied email will also be used as the linked email for
the new user.
</p>
<form action="auth/invite/<%= invite.token %>" onsubmit="formAJAX(this)" evalAJAX="emailSent()">
<div class="form-group">
<label class="control-label">Email</label>
<div class="input-group mb-3">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-at"></i></span>
</div>
<input type="email" name="mail" class="form-control" placeholder="jsmith@gmail.com" validate="email:3" />
</div>
</div>
<button type="submit" class="btn btn-outline-dark"><i class="fad fa-paper-plane"></i> Send It!</button>
</form>
</div>
</div>
</div>
</div>
</div>
<%- include('bottom') %>

100
nodejs/views/login.ejs Executable file
View File

@ -0,0 +1,100 @@
<%- include('top') %>
<script type="text/javascript">
app.auth.isLoggedIn(function(error, isLoggedIn){
if(isLoggedIn){
window.location.href = app.util.getUrlParameter('redirect') || '/';
}
})
$(document).ready(function(){
});
</script>
<div class="row">
<div class="card-deck">
<div class="shadow-lg card mb-3">
<div class="card-header shadow">
Password Log in
</div>
<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);window.location.href = app.util.getUrlParameter('redirect') || '/';">
<input type="hidden" name="redirect" value="<%= redirect %>">
<div class="form-group">
<label class="control-label">User name</label>
<div class="input-group mb-3 shadow">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-user"></i></span>
</div>
<input type="text" name="uid" class="form-control" placeholder="jsmith" validate="user:3" />
</div>
</div>
<div class="form-group">
<label class="control-label">Password</label>
<div class="input-group mb-3 shadow">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-key"></i></span>
</div>
<input type="password" name="password" class="form-control" placeholder="hunter123!" validate=":3" />
</div>
</div>
<button type="submit" class="btn btn-outline-dark"><i class="fad fa-sign-in"></i> Log in</button>
</form>
</div>
</div>
<div class="shadow-lg card border-danger mb-3">
<div class="card-header shadow">
Social Login
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<h3>Coming soon!</h3>
<p>
<ul class="list-group">
<li class="list-group-item"><i class="fab fa-google"></i> Login with google OATH</li>
<li class="list-group-item"><i class="fab fa-github"></i> Login with github OATH</li>
<li class="list-group-item"><i class="fab fa-facebook"></i> Login with facebook OATH</li>
</ul>
</p>
</div>
</div>
<div class="shadow-lg card mb-3">
<div class="card-header shadow">
Password Reset
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<p>
Forgot your password? Or your user name? No problem! Just
enter you email address below and if you are in our system,
we will email with the required information to get back up
and running!
</p>
<form action="auth/resetpassword" onsubmit="formAJAX(this)">
<input type="hidden" name="redirect" value="<%= redirect %>">
<div class="form-group">
<label class="control-label">Email</label>
<div class="input-group mb-3 shadow">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-at"></i></span>
</div>
<input type="email" name="mail" class="form-control" placeholder="jsmith@gmail.com" validate="email:3" />
</div>
</div>
<button type="submit" class="btn btn-outline-dark"><i class="fad fa-question"></i> Help me!</button>
</form>
</div>
</div>
</div>
</div>
<%- include('bottom') %>

View File

@ -0,0 +1,43 @@
<%- include('top') %>
<script type="text/javascript">
$(document).ready(function(){
});
</script>
<div class="row" style="display:none">
<div class="col-md-12">
<div class="card mb-3 shadow-lg">
<div class="card-header">
Password reset
</div>
<div class="card-header shadow actionMessage" style="display:none">
</div>
<div class="card-body">
<p>
<form action="auth/resetpassword/<%= token.token%>" method="post" onsubmit="formAJAX(this)">
<div class="form-group">
<label class="control-label">Password</label>
<div class="input-group mb-3 shadow">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-key"></i></span>
</div>
<input type="password" name="userPassword" class="form-control" placeholder="hunter123!" validate=":3" />
</div>
</div>
<div class="form-group">
<label class="control-label">Again</label>
<div class="input-group mb-3 shadow">
<div class="input-group-prepend">
<span class="input-group-text" ><i class="fad fa-key"></i></span>
</div>
<input type="password" name="password" class="form-control" placeholder="hunter123!" validate="eq:userPassword" />
</div>
</div>
<button type="submit" class="btn btn-outline-dark">Change</button>
</form>
</p>
</div>
</div>
</div>
</div>
<%- include('bottom') %>

39
nodejs/views/top.ejs Executable file
View File

@ -0,0 +1,39 @@
<!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>SSO Manager - Theta 42</title>
<!-- CSS are placed here -->
<link rel="stylesheet" href="/static/css/bootstrap-4.4.1.min.css">
<link rel='stylesheet' href='/static/css/styles.css' />
<!-- Scripts are placed here -->
<script type="text/javascript" src='/static/js/jquery-3.5.0.min.js'></script>
<script type="text/javascript" src="/static/js/popper-1.16.0.min.js"></script>
<script type="text/javascript" src="/static/js/bootstrap-4.4.1.min.js"></script>
<script type="text/javascript" src="/static/js/all.min.js"></script>
<script type="text/javascript" src='/static/js/mustache.min.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 -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<header class="shadow d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">
<h5 class="hover-effect my-0 mr-md-auto font-weight-normal">SSO Manager - Theta 42</h5>
<nav class="my-2 my-md-0 mr-md-3">
<a class="text-dark hover-effect" href="/"><i class="fad fa-tachometer-alt-fastest"></i>Home</a>
<a class="text-dark hover-effect" href="/users"><i class="fad fa-users"></i>Users</a>
<a class="text-dark hover-effect" href="/groups"><i class="fad fa-users-class"></i>Groups</a>
</nav>
<a class="hover-effect btn btn-outline-primary" onclick="app.auth.logOut(e => window.location.href='/')"><i class="fas fa-sign-out"></i> Log Out</a>
</header>
<!-- Container -->
<div class="container">

View File

@ -0,0 +1,41 @@
<form action="user/" method="post" onsubmit="formAJAX(this)">
<input type="hidden" class="form-control" name="delete" value="false" />
<div class="form-group">
<label class="control-label">First name</label>
<input type="text" class="form-control shadow" name="givenName" placeholder="John" validate=":3" />
</div>
<div class="form-group">
<label class="control-label">Last name</label>
<input type="text" class="form-control shadow" name="sn" placeholder="smith" validate=":3" />
</div>
<div class="form-group">
<label class="control-label">Email</label>
<input type="text" class="form-control shadow" name="mail" placeholder="jsmith@gmail.com" validate="email:3" />
</div>
<div class="form-group">
<label class="control-label">SSH Public Key</label>
<input type="text" class="form-control shadow" name="sshPublicKey" placeholder="ssh-rsa AAAAB3NzaC1yc2EAAAADAQ..." />
</div>
<div class="form-group">
<label class="control-label">Mobile Phone</label>
<input type="text" class="form-control shadow" name="mobile" placeholder="9175551234" validate=":9" />
</div>
<div class="form-group">
<label class="control-label">Password</label>
<input type="password" class="form-control shadow" name="userPassword" 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 shadow" name="passwordMatch" placeholder="Retype password" validate="eq:userPassword"/>
</div>
<div class="form-group">
<label class="control-label">User Description (Optional)</label>
<textarea class="form-control shadow" name="description" placeholder="Admin group for gitea app"></textarea>
</div>
<button type="submit" class="btn btn-outline-dark">Add</button>
</form>

96
nodejs/views/users.ejs Executable file
View File

@ -0,0 +1,96 @@
<%- include('top') %>
<script id="rowTemplate" type="text/html">
<tr class="" action="user/password/{{ username }}" method="put" evalAJAX="$form.trigger('reset')">
<td>
{{ uidNumber }}
</td>
<td>
<a href='/users/{{uid}}'>{{ uid }}</a>
</td>
<td>
{{givenName}} {{sn}}
</td>
<td>
{{mail}}
</td>
<td>
{{#sudoUser}}<i class="fad fa-check-square"></i>{{/sudoUser}}
</td>
<td>
{{#sshPublicKey}}<i class="fad fa-check-square"></i>{{/sshPublicKey}}
</td>
<td>
<form action="user/{{uid}}" method="delete" onsubmit="formAJAX(this)" evalAJAX="renderUsers('Deleted {{uid}}', 'success')">
<button type="submit" class="btn btn-sm btn-danger">
<i class="fad fa-user-slash"></i>
</button>
</form>
</td>
</tr>
</script>
<script type="text/javascript">
function renderUsers(actionMessage, type){
var rowTemplate = $('#rowTemplate').html();
var $target = $('#tableAJAX');
$target.html('').hide();
app.util.actionMessage('Refreshing user list...', $target);
app.user.list(function(error, data){
$.each( data.results, function(key, value) {
if(value.uidNumber<1500) return;
user_row = Mustache.render(rowTemplate, value);
$target.append(user_row);
});
$target.fadeIn('slow');
app.util.actionMessage(actionMessage || '', $target, type || 'info');
});
}
$(document).ready(function(){
renderUsers(); //populate the table
$('form[action="user/"]').attr('evalAJAX', 'renderUsers("User added", "success")')
});
</script>
<div class="row" style="display:none">
<div class="col-md-4">
<div class="card shadow-lg">
<div class="card-header">
<i class="fas fa-user-plus"></i>
Add new user
</div>
<div class="card-header actionMessage" style="display:none"></div>
<div class="card-body">
<%- include('user_form') %>
</div>
</div>
</div>
<div class="col-md-8">
<div class="card shadow">
<div class="card-header">
<i class="fad fa-th-list"></i>
User List
</div>
<div class="card-header actionMessage" style="display:none"></div>
<table class="card-body table table-striped" style="margin-bottom:0">
<thead>
<th>ID</th>
<th>User Name</th>
<th>Name</th>
<th>eMail</th>
<th>Sudo</th>
<th>Key</th>
<th></th>
</thead>
<tbody id="tableAJAX">
<!-- ajax loaded table -->
</tbody>
</table>
</div>
</div>
</div>
<%- include('bottom') %>