mirror of
https://github.com/janishutz/libreevent.git
synced 2025-11-25 13:24:24 +00:00
login system progress
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* myevent - pwdmanager.js
|
||||
*
|
||||
* Created by Janis Hutz 03/26/2023, Licensed under the GPL V3 License
|
||||
* https://janishutz.com, development@janishutz.com
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
These functions are required to verify user login and to create new users
|
||||
and to hash new passwords (if user changes password.) This here is only
|
||||
used for the admin panel, another one is used for the normal user accounts
|
||||
to separate the two for additional security.
|
||||
*/
|
||||
|
||||
// import and init
|
||||
const bcrypt = require( 'bcrypt' );
|
||||
const db = require( '../backend/db/db.js' );
|
||||
|
||||
module.exports.checkpassword = function checkpassword ( username, password ) {
|
||||
return new Promise( resolve => {
|
||||
db.getData( 'admin', username ).then( data => {
|
||||
resolve( bcrypt.compareSync( password, data ) );
|
||||
} );
|
||||
} );
|
||||
};
|
||||
@@ -8,10 +8,45 @@
|
||||
*/
|
||||
|
||||
const path = require( 'path' );
|
||||
const pwdmanager = require( './pwdmanager.js' );
|
||||
|
||||
|
||||
module.exports = ( app, settings ) => {
|
||||
/*
|
||||
Static routes for files like login screen, css, js and assets. Js and assets require login
|
||||
*/
|
||||
app.get( '/admin/login', ( request, response ) => {
|
||||
response.sendFile( path.join( __dirname + '/ui/login.html' ) );
|
||||
if ( request.session.loggedIn ) {
|
||||
response.redirect( '/admin' );
|
||||
} else {
|
||||
response.sendFile( path.join( __dirname + '/ui/login.html' ) );
|
||||
}
|
||||
} );
|
||||
|
||||
app.get( '/admin/loginLangPack', ( request, response ) => {
|
||||
response.sendFile( path.join( __dirname + '/ui/js/loginLangPack.js' ) );
|
||||
} );
|
||||
|
||||
app.get( '/admin/css/:file', ( request, response ) => {
|
||||
response.sendFile( path.join( __dirname + '/ui/css/' + request.params.file ) );
|
||||
} );
|
||||
|
||||
/*
|
||||
Admin login route that checks the password and, if enabled in settings, redirects to 2fa page or directly to admin panel
|
||||
*/
|
||||
app.post( '/admin/auth', ( request, response ) => {
|
||||
pwdmanager.checkpassword( request.body.mail, request.body.pwd ).then( data => {
|
||||
if ( data ) {
|
||||
if ( settings.twoFA ) {
|
||||
response.sendFile( path.join( __dirname + '../admin/ui/2fa.html' ) );
|
||||
} else {
|
||||
request.session.loggedIn = true;
|
||||
response.redirect( '/admin' );
|
||||
}
|
||||
} else {
|
||||
response.send( 'Password wrong' );
|
||||
}
|
||||
} );
|
||||
} );
|
||||
|
||||
/*
|
||||
|
||||
98
src/server/admin/ui/css/loginstyle.css
Normal file
98
src/server/admin/ui/css/loginstyle.css
Normal file
@@ -0,0 +1,98 @@
|
||||
:root, :root.light {
|
||||
--background-color: rgb(202, 223, 255);
|
||||
--secondary-background: white;
|
||||
--primary-color: black;
|
||||
--secondary-color: blue;
|
||||
--secondary-hover: darkblue;
|
||||
}
|
||||
|
||||
:root.dark {
|
||||
--background-color: rgb(42, 44, 56);
|
||||
--secondary-background: rgb(19, 20, 32);
|
||||
--primary-color: white;
|
||||
--secondary-color: rgb(94, 94, 226);
|
||||
--secondary-hover: rgb(155, 155, 255);
|
||||
}
|
||||
|
||||
@media ( prefers-color-scheme: dark ) {
|
||||
:root {
|
||||
--background-color: rgb(42, 44, 56);
|
||||
--secondary-background: rgb(19, 20, 32);
|
||||
--primary-color: white;
|
||||
--secondary-color: rgb(94, 94, 226);
|
||||
--secondary-hover: rgb(155, 155, 255);
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--background-color);
|
||||
font-family: sans-serif;
|
||||
font-size: calc(12pt + 0.35vw);
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.login-app {
|
||||
border-radius: 50px;
|
||||
margin-top: 2%;
|
||||
background-color: var(--secondary-background);
|
||||
color: var(--primary-color);
|
||||
width: 60%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form {
|
||||
width: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 4%;
|
||||
margin-bottom: 4%;
|
||||
}
|
||||
|
||||
.button {
|
||||
text-decoration: none;
|
||||
color: var(--primary-color);
|
||||
background-color: var(--secondary-color);
|
||||
padding: 15px;
|
||||
border-radius: 30px;
|
||||
transition: 1s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
transition: ease-in-out 0.2s;
|
||||
background-color: var(--secondary-hover);
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.input {
|
||||
padding: 1%;
|
||||
width: 80%;
|
||||
margin-bottom: 3%;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.selector {
|
||||
background-color: lightblue;
|
||||
border-radius: 20px;
|
||||
padding: 0.5%;
|
||||
border-style: solid;
|
||||
border-color: blue;
|
||||
}
|
||||
32
src/server/admin/ui/js/loginLangPack.js
Normal file
32
src/server/admin/ui/js/loginLangPack.js
Normal file
@@ -0,0 +1,32 @@
|
||||
let themeSelector2 = document.getElementById( 'theme' );
|
||||
let languageSelector = document.getElementById( 'lang' );
|
||||
let mailLabel = document.getElementById( 'mailLabel' );
|
||||
let pwdLabel = document.getElementById( 'pwdLabel' );
|
||||
let login = document.getElementById( 'login' );
|
||||
|
||||
languageSelector.value = sessionStorage.getItem( 'lang' );
|
||||
|
||||
function langUpdate () {
|
||||
if ( sessionStorage.getItem( 'lang' ) === 'de' ) {
|
||||
themeSelector2.options[0].innerHTML = 'Automatisch';
|
||||
themeSelector2.options[1].innerHTML = 'Hellmodus';
|
||||
themeSelector2.options[2].innerHTML = 'Dunkelmodus';
|
||||
mailLabel.innerHTML = 'Email - Adresse';
|
||||
pwdLabel.innerHTML = 'Passwort';
|
||||
login.value = 'Anmelden';
|
||||
} else {
|
||||
themeSelector2.options[0].innerHTML = 'System theme';
|
||||
themeSelector2.options[1].innerHTML = 'Light';
|
||||
themeSelector2.options[2].innerHTML = 'Dark';
|
||||
mailLabel.innerHTML = 'Email address';
|
||||
pwdLabel.innerHTML = 'Password';
|
||||
login.value = 'Log in';
|
||||
}
|
||||
}
|
||||
|
||||
function changeLang () {
|
||||
sessionStorage.setItem( 'lang', languageSelector.value );
|
||||
langUpdate();
|
||||
}
|
||||
|
||||
langUpdate();
|
||||
@@ -5,88 +5,17 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login :: myevent - admin panel</title>
|
||||
<style>
|
||||
body {
|
||||
background-color: rgb(202, 223, 255);
|
||||
font-family: sans-serif;
|
||||
font-size: calc(12pt + 0.35vw);
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.login-app {
|
||||
border-radius: 50px;
|
||||
margin-top: 2%;
|
||||
background-color: white;
|
||||
width: 60%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form {
|
||||
width: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-top: 4%;
|
||||
margin-bottom: 4%;
|
||||
}
|
||||
|
||||
.button {
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
background-color: blue;
|
||||
padding: 15px;
|
||||
border-radius: 30px;
|
||||
transition: 1s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
transition: ease-in-out 0.2s;
|
||||
background-color: darkblue;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.input {
|
||||
padding: 1%;
|
||||
width: 80%;
|
||||
margin-bottom: 3%;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.top-bar {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: end;
|
||||
justify-content: end;
|
||||
}
|
||||
|
||||
.selector {
|
||||
background-color: lightblue;
|
||||
border-radius: 20px;
|
||||
padding: 0.5%;
|
||||
border-style: solid;
|
||||
border-color: blue;
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/admin/css/loginstyle.css">
|
||||
<script defer src="/admin/loginLangPack"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<div class="top-bar">
|
||||
<select name="lang" id="lang" class="selector">
|
||||
<select name="lang" id="lang" class="selector" onchange="changeLang();">
|
||||
<option value="en">English</option>
|
||||
<option value="de">Deutsch</option>
|
||||
</select>
|
||||
<select name="theme" id="theme" class="selector">
|
||||
<select name="theme" id="theme" class="selector" onchange="toggleTheme();">
|
||||
<option value="system">System theme</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
@@ -97,13 +26,52 @@
|
||||
<h1>Login</h1>
|
||||
<footer>myevent - admin panel</footer>
|
||||
<form action="/admin/auth" method="post" class="form">
|
||||
<label for="mail">Email address</label><br>
|
||||
<label for="mail" id="mailLabel">Email address</label><br>
|
||||
<input type="email" id="mail" name="mail" required class="input"><br>
|
||||
<label for="pwd">Password</label><br>
|
||||
<label for="pwd" id="pwdLabel">Password</label><br>
|
||||
<input type="password" id="pwd" name="pwd" required class="input"><br>
|
||||
<input type="submit" value="Log in" class="button">
|
||||
<input type="submit" value="Log in" class="button" id="login">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
||||
<script>
|
||||
let themeSelector = document.getElementById( 'theme' );
|
||||
|
||||
if ( sessionStorage.getItem( 'theme' ) ) {
|
||||
themeSelector.value = sessionStorage.getItem( 'theme' );
|
||||
}
|
||||
|
||||
if ( window.matchMedia( '(prefers-color-scheme: dark)' ).matches || themeSelector.value === 'dark' ) {
|
||||
document.documentElement.classList.add( 'dark' );
|
||||
} else {
|
||||
document.documentElement.classList.add( 'light' );
|
||||
};
|
||||
|
||||
setTimeout( activate, 500 );
|
||||
|
||||
function activate () {
|
||||
$( 'body' ).css( 'transition', '0.5s' );
|
||||
}
|
||||
|
||||
function toggleTheme () {
|
||||
sessionStorage.setItem( 'theme', themeSelector.value );
|
||||
if ( themeSelector.value === 'dark' ) {
|
||||
document.documentElement.classList.remove( 'light' );
|
||||
document.documentElement.classList.add( 'dark' );
|
||||
} else if ( themeSelector.value === 'light' ) {
|
||||
document.documentElement.classList.remove( 'dark' );
|
||||
document.documentElement.classList.add( 'light' );
|
||||
} else if ( themeSelector.value === 'system' ) {
|
||||
if ( window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {
|
||||
document.documentElement.classList.remove( 'light' );
|
||||
document.documentElement.classList.add( 'dark' );
|
||||
} else {
|
||||
document.documentElement.classList.remove( 'dark' );
|
||||
document.documentElement.classList.add( 'light' );
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
76
src/server/admin/ui/setup.html
Normal file
76
src/server/admin/ui/setup.html
Normal file
@@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Login :: myevent - admin panel</title>
|
||||
<link rel="stylesheet" href="/admin/css/loginstyle.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="content">
|
||||
<div class="top-bar">
|
||||
<select name="lang" id="lang" class="selector" onchange="changeLang();">
|
||||
<option value="en">English</option>
|
||||
<option value="de">Deutsch</option>
|
||||
</select>
|
||||
<select name="theme" id="theme" class="selector" onchange="toggleTheme()">
|
||||
<option value="system">System theme</option>
|
||||
<option value="light">Light</option>
|
||||
<option value="dark">Dark</option>
|
||||
</select>
|
||||
</div>
|
||||
<a href="https://myevent.janishutz.com"><img src="/assets/logo.png" alt="myevent-logo" style="height: 35vh;"></a>
|
||||
<div class="login-app">
|
||||
<h1>Setup</h1>
|
||||
<footer>myevent - admin panel</footer>
|
||||
<form action="/admin/auth" method="post" class="form">
|
||||
<label for="mail">Email address</label><br>
|
||||
<input type="email" id="mail" name="mail" required class="input"><br>
|
||||
<label for="pwd">Password</label><br>
|
||||
<input type="password" id="pwd" name="pwd" required class="input"><br>
|
||||
<input type="submit" value="Log in" class="button">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
|
||||
<script>
|
||||
let themeSelector = document.getElementById( 'theme' );
|
||||
|
||||
if ( sessionStorage.getItem( 'theme' ) ) {
|
||||
themeSelector.value = sessionStorage.getItem( 'theme' );
|
||||
}
|
||||
|
||||
if ( window.matchMedia( '(prefers-color-scheme: dark)' ).matches || themeSelector.value === 'dark' ) {
|
||||
document.documentElement.classList.add( 'dark' );
|
||||
} else {
|
||||
document.documentElement.classList.add( 'light' );
|
||||
};
|
||||
|
||||
setTimeout( activate, 500 );
|
||||
|
||||
function activate () {
|
||||
$( 'body' ).css( 'transition', '0.5s' );
|
||||
}
|
||||
|
||||
function toggleTheme () {
|
||||
sessionStorage.setItem( 'theme', themeSelector.value );
|
||||
if ( themeSelector.value === 'dark' ) {
|
||||
document.documentElement.classList.remove( 'light' );
|
||||
document.documentElement.classList.add( 'dark' );
|
||||
} else if ( themeSelector.value === 'light' ) {
|
||||
document.documentElement.classList.remove( 'dark' );
|
||||
document.documentElement.classList.add( 'light' );
|
||||
} else if ( themeSelector.value === 'system' ) {
|
||||
if ( window.matchMedia( '(prefers-color-scheme: dark)' ).matches ) {
|
||||
document.documentElement.classList.remove( 'light' );
|
||||
document.documentElement.classList.add( 'dark' );
|
||||
} else {
|
||||
document.documentElement.classList.remove( 'dark' );
|
||||
document.documentElement.classList.add( 'light' );
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user