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

15
lib/config.mjs Normal file
View file

@ -0,0 +1,15 @@
import {
parse as parseYaml
} from 'yaml';
import {
readFileSync
} from "node:fs";
export async function getConfig() {
return parseYaml(
readFileSync('config.yaml', 'utf-8')
);
}

107
lib/mysql.mjs Normal file
View file

@ -0,0 +1,107 @@
import mysql from "mysql2/promise";
import {
generateOTPSecret
} from "./otp.mjs";
// Create the connection to database
const connection = await mysql.createConnection({
host: '10.0.0.31',
port: 33063,
database: 'glauth',
user: 'glauth',
password: 'b848dc7aa44b66bbcc1e5991a6ae45ce'
});
export async function login(username, password) {
try {
const [rows] = await connection.execute('SELECT id, uidnumber, name, otpsecret FROM `users` WHERE `name` = ? AND `passsha256` = ? AND `disabled` = 0', [username, password]);
if (rows.length == 0) {
throw new Error(`user ${username} not found.`);
}
if (rows.length > 1) {
throw new Error("more than 1 user found.");
}
console.log(`user ${rows[0].name} logged in.`);
return rows[0];
} catch (error) {
console.log(`login failed: ${error.message}`);
return null;
}
}
export async function getUser(userid) {
try {
const [rows] = await connection.execute('SELECT uidnumber, name, givenname, sn, mail, custattr FROM `users` WHERE `id` = ?', [userid]);
if (rows.length == 0) {
throw new Error("no user found.");
}
return rows[0];
} catch (error) {
return null;
}
}
export async function getUserMFA(userid) {
try {
const [rows] = await connection.execute('SELECT otpsecret, yubikey FROM `users` WHERE `id` = ?', [userid]);
if (rows.length == 0) {
throw new Error("no user found.");
}
return rows[0];
} catch (error) {
return null;
}
}
export async function setOTPSecret(userid, otpsecret) {
try {
await connection.execute('UPDATE `users` SET `otpsecret` = ? WHERE `id` = ?', [otpsecret, userid]);
return true;
} catch (error) {
return false;
}
}
export async function getUsers() {
let [mysqlUsers] = await connection.execute('SELECT id, name, uidnumber, mail, disabled FROM `users`', []);
return mysqlUsers;
}
export async function getGroups() {
let [mysqlGroups] = await connection.execute('SELECT * FROM `ldapgroups`', []);
return mysqlGroups;
}
export async function getUserGroups(userid) {
try {
let [mysqlUsers] = await connection.execute('SELECT primarygroup, othergroups FROM `users` WHERE `id` = ?', [userid]);
let [mysqlGroups] = await connection.execute('SELECT * FROM `ldapgroups`', []);
mysqlGroups = mysqlGroups.map((mysqlGroup) => {
return {
id: mysqlGroup.id,
name: mysqlGroup.name
}
});
let result = [];
if (mysqlUsers[0].primarygroup != '') {
}
return true;
} catch (error) {
return false;
}
}

59
lib/otp.mjs Normal file
View file

@ -0,0 +1,59 @@
import qrcode from "qrcode";
import {
Secret,
TOTP
} from "otpauth";
import {
getConfig
} from "./config.mjs";
import {
setOTPSecret
} from "./mysql.mjs";
let appConfig = await getConfig();
export function generateOTPSecret() {
return new Promise((resolve, reject) => {
let otpSecret = new Secret({ length: 20 });
resolve(otpSecret.base32);
})
}
export function generateOTPQRCode(account, otpsecret) {
return new Promise(async (resolve, reject) => {
let totp = new TOTP({
issuer: appConfig.mfa.otp.issuer,
label: account,
algorithm: "SHA1",
digits: 6,
period: 30,
secret: otpsecret
});
qrcode.toDataURL(totp.toString(), (error, url) => {
resolve(url)
})
})
}
export function validateOTPCode(account, otpsecret, token) {
return new Promise((resolve, reject) => {
let totp = new TOTP({
issuer: appConfig.mfa.otp.issuer,
label: account,
algorithm: "SHA1",
digits: 6,
period: 30,
secret: otpsecret
});
resolve(totp.validate({ token, window: 2 }));
});
}
export async function saveOTPSecret(userid, otpsecret) {
setOTPSecret(userid, otpsecret)
}