initial upload

This commit is contained in:
Kai Waggeling 2025-05-17 16:40:38 +02:00
parent 4c2141d89d
commit 2a9bd4e81b
33 changed files with 1238 additions and 0 deletions

36
routes/admin/[page].mjs Normal file
View file

@ -0,0 +1,36 @@
import {
getUsers,
getGroups
} from "../../lib/mysql.mjs";
export const get = async function (request, response) {
// if (!request.isLoginCompleted()) {
// response.redirect('/login');
// return;
// }
switch (request.params.page) {
case 'users':
response.render(`ui/admin.njk`, {
page: 'users',
users: await getUsers()
});
break;
case 'groups':
response.render(`ui/admin.njk`, {
page: 'groups',
groups: await getGroups()
});
break;
default:
response.redirect('/admin/users');
break;
}
}
export const post = async function (request, response) {
console.log(request.body);
response.redirect("/login");
}

4
routes/admin/index.mjs Normal file
View file

@ -0,0 +1,4 @@
export const get = async function (request, response) {
response.redirect('/admin/users');
}

78
routes/login.mjs Normal file
View file

@ -0,0 +1,78 @@
import crypto from "crypto";
import {
login,
getUser,
getUserMFA
} from "../lib/mysql.mjs";
import {
validateOTPCode
} from "../lib/otp.mjs";
export const get = async function(request, response) {
if (typeof request.session.userid != 'string') {
response.render(`ui/login.njk`, {
step: 'login'
});
return;
}
if (request.session.otpVerified != true) {
response.render(`ui/login.njk`, {
step: 'otp'
});
return;
}
}
export const post = async function(request, response) {
if (typeof request.body.username == 'string' && typeof request.body.password == 'string') {
let username = request.body.username;
let password = crypto.createHash('sha256').update(request.body.password).digest('hex')
let loginResult = await login(username, password)
if (loginResult == null) {
response.render(`ui/login.njk`, {
step: 'login',
error: 'login failed'
});
return;
}
request.session.userid = loginResult.id;
request.session.login = {
completed: false,
otpVerified: false
}
request.session.save();
if (loginResult.otpsecret != '' && loginResult.yubikey != '') {
response.render(`ui/login.njk`, {
step: 'otp'
});
return;
} else {
request.session.login.completed = true;
response.redirect('/profile')
}
} else if (typeof request.body.otpToken == 'string') {
let otpToken = request.body.otpToken;
let userData = await getUser(request.session.userid);
let mfaData = await getUserMFA(request.session.userid);
let validationResult = await validateOTPCode(userData.mail, mfaData.otpsecret, otpToken);
if (validationResult != null) {
request.session.login.completed = true;
response.redirect('/profile');
} else {
request.session.destroy();
response.render(`ui/login.njk`, {
step: 'login',
error: 'otp failed'
});
}
}
}

5
routes/logout.mjs Normal file
View file

@ -0,0 +1,5 @@
export const get = async function(request, response) {
request.session.destroy();
response.render(`ui/logout.njk`);
}

59
routes/profile/[page].mjs Normal file
View file

@ -0,0 +1,59 @@
import {
getUser,
getUserMFA
} from "../../lib/mysql.mjs";
import {
generateOTPQRCode
} from "../../lib/otp.mjs";
export const get = async function(request, response) {
if (!request.isLoginCompleted()) {
response.redirect('/login');
return;
}
let userData = await getUser(request.session.userid);
let mfaData = await getUserMFA(request.session.userid);
switch (request.params.page) {
case 'personal':
response.render(`ui/profile.njk`, {
page: 'profile/personal',
data: {
firstName: userData.givenname,
lastName: userData.sn,
mail: userData.mail,
}
});
break;
case 'security':
response.render(`ui/profile.njk`, {
page: 'profile/security',
otp: {
active: mfaData.otpsecret != '' ? true : false,
qrcode: await generateOTPQRCode(userData.mail, mfaData.otpsecret)
}
});
break;
case 'createOTPSecret':
response.render(`ui/profile.njk`, {
page: 'profile/createOTPSecret',
otp: {
active: mfaData.otpsecret != '' ? true : false,
qrcode: await generateOTPQRCode(userData.mail, mfaData.otpsecret)
}
});
break;
default:
response.redirect('/page/personal');
break;
}
}
export const post = async function(request, response) {
console.log(request.body);
response.redirect("/login");
}

9
routes/profile/index.mjs Normal file
View file

@ -0,0 +1,9 @@
export const get = async function (request, response) {
if (!request.isLoginCompleted()) {
response.redirect('/login');
return;
}
response.redirect('/profile/personal');
}

View file

@ -0,0 +1,62 @@
import {
generateOTPQRCode,
generateOTPSecret,
validateOTPCode,
saveOTPSecret
} from "../../../lib/otp.mjs";
import {
getUser,
getUserMFA
} from "../../../lib/mysql.mjs";
export const get = async function (request, response) {
if (!request.isLoginCompleted()) {
response.redirect('/login');
return;
}
if (typeof request.session.otpConfig != 'object') {
request.session.otpConfig = {
completed: false,
otpSecret: await generateOTPSecret()
}
}
let userData = await getUser(request.session.userid);
let otpsecret = request.session.otpConfig.otpSecret;
response.render(`ui/profile.njk`, {
page: 'otp/create',
otp: {
active: request.session.otpConfig.completed != '' ? true : false,
qrcode: await generateOTPQRCode(userData.name, otpsecret),
otpsecret: request.session.otpConfig.otpSecret
}
});
}
export const post = async function (request, response) {
if (!request.isLoginCompleted()) {
response.redirect('/login');
return;
}
let userData = await getUser(request.session.userid);
if (validateOTPCode(userData.name, request.body.otpsecret, request.body.otpcode)) {
saveOTPSecret(request.session.userid, request.body.otpsecret)
response.render(`ui/messages/success.njk`, {
message: {
title: 'OTP Secret created!',
text: 'Your new OTP-Secret was successfull generated',
link: '/profile/security'
}
});
} else {
response.redirect('/profile/otp/create')
}
}

View file

@ -0,0 +1,62 @@
import {
generateOTPQRCode,
generateOTPSecret,
validateOTPCode,
saveOTPSecret
} from "../../../lib/otp.mjs";
import {
getUser,
getUserMFA
} from "../../../lib/mysql.mjs";
export const get = async function (request, response) {
if (!request.isLoginCompleted()) {
response.redirect('/login');
return;
}
if (typeof request.session.otpConfig != 'object') {
request.session.otpConfig = {
completed: false,
otpSecret: await generateOTPSecret()
}
}
let userData = await getUser(request.session.userid);
let otpsecret = request.session.otpConfig.otpSecret;
response.render(`ui/profile.njk`, {
page: 'otp/create',
otp: {
active: request.session.otpConfig.completed != '' ? true : false,
qrcode: await generateOTPQRCode(userData.name, otpsecret),
otpsecret: request.session.otpConfig.otpSecret
}
});
}
export const post = async function (request, response) {
if (!request.isLoginCompleted()) {
response.redirect('/login');
return;
}
let userData = await getUser(request.session.userid);
if (validateOTPCode(userData.name, request.body.otpsecret, request.body.otpcode)) {
saveOTPSecret(request.session.userid, request.body.otpsecret)
response.render(`ui/messages/success.njk`, {
message: {
title: 'OTP Secret created!',
text: 'Your new OTP-Secret was successfull generated',
link: '/profile/security'
}
});
} else {
response.redirect('/profile/otp/create')
}
}