Files
radixOS/src/services/authenticationManager.js
2026-04-26 07:43:31 +00:00

193 lines
5.0 KiB
JavaScript

const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');
class AuthenticationManager {
constructor(model, secretKey) {
this.Authentication = model;
this.SECRET_KEY = secretKey;
}
// =========================================================
// USER
// =========================================================
async findUser(sAMAccountName) {
return this.Authentication.findOne({
where: { sAMAccountName }
});
}
// =========================================================
// PASSWORD
// =========================================================
async setPassword(sAMAccountName, password) {
const user = await this.findUser(sAMAccountName);
if (!user) {
return { token: null, levelId: 2, message: 'Unbekannter User' };
}
user.password = await bcrypt.hash(password, 10);
await user.save();
return { token: null, levelId: 0, message: 'Passwort gesetzt' };
}
// =========================================================
// LOGIN
// =========================================================
async login(sAMAccountName, password) {
const user = await this.findUser(sAMAccountName);
if (!user) {
return { token: null, levelId: 2, message: 'Unbekannter Benutzer' };
}
if (!user.password) {
await this.setPassword(sAMAccountName, password);
return { token: null, levelId: 1, message: 'Benutzer nicht registriert' };
}
const ok = await bcrypt.compare(password, user.password);
if (!ok) {
return { token: null, levelId: 2, message: 'Falsches Passwort' };
}
const token = jwt.sign(
{
ObjectGUID: user.ObjectGUID,
sAMAccountName: user.sAMAccountName
},
this.SECRET_KEY,
{ expiresIn: '1y' }
);
user.refreshtoken = token;
user.online = true;
await user.save();
return { token, levelId: 0, message: 'Erfolgreich angemeldet' };
}
// =========================================================
// LOGOUT
// =========================================================
async logout(sAMAccountName) {
const user = await this.findUser(sAMAccountName);
if (!user) {
return { token: null, levelId: 2, message: 'User nicht gefunden' };
}
user.refreshtoken = null;
user.online = false;
await user.save();
return { token: null, levelId: 0, message: 'Erfolgreich abgemeldet' };
}
// =========================================================
// VERIFY TOKEN
// =========================================================
async verifyUserToken(sAMAccountName) {
const user = await this.findUser(sAMAccountName);
if (!user || !user.refreshtoken) {
return { valid: false, levelId: 1 };
}
try {
const payload = jwt.verify(user.refreshtoken, this.SECRET_KEY);
return {
valid: true,
user,
payload
};
} catch {
return { valid: false, levelId: 4 };
}
}
// =========================================================
// 🔥 MIDDLEWARE BLEIBT HIER
// =========================================================
authenticate() {
return async (req, res, next) => {
try {
// =====================================================
// 🔥 GLOBAL PUBLIC ROUTE BYPASS (ROBUST)
// =====================================================
const url = req.originalUrl.split('?')[0];
const publicRoutes = [
'/login',
'/public'
];
const isPublicRoute = publicRoutes.some(route =>
url === route || url.startsWith(route + '/')
);
if (isPublicRoute) {
return next();
}
// =====================================================
// 🔐 AUTH FLOW
// =====================================================
const sAMAccountName = req.cookies?.sAMAccountName;
if (!sAMAccountName) {
return res.redirect('/login');
}
const user = await this.findUser(sAMAccountName);
if (!user || !user.active) {
return res.redirect('/login');
}
let payload;
try {
payload = jwt.verify(user.refreshtoken, this.SECRET_KEY);
} catch {
return res.redirect('/login');
}
const rbac = await this.rbac.resolvePermissions(user.ObjectGUID);
const normalized = this.rbac.normalize(rbac.permissions);
const isSuperAdmin = this.rbac.isSuperAdmin(normalized);
req.user = {
...user.toJSON(),
jwt: payload,
groups: rbac.groups,
roles: rbac.roles,
permissions: normalized,
isSuperAdmin
};
next();
} catch (err) {
console.error(err);
return res.redirect('/login');
}
};
}
}
module.exports = AuthenticationManager;