Added Krank Button, LDAP Sync auth

This commit is contained in:
Carsten Graf
2026-01-23 10:32:20 +01:00
parent 743a103465
commit f7b1322ae6
4 changed files with 291 additions and 73 deletions

View File

@@ -113,6 +113,19 @@ class LDAPService {
return Array.isArray(attr.values) ? attr.values[0] : attr.values;
}
/**
* Escaped einen Wert für LDAP-Filter (verhindert LDAP-Injection)
*/
static escapeLDAPFilter(value) {
if (!value) return '';
return value
.replace(/\\/g, '\\5c')
.replace(/\*/g, '\\2a')
.replace(/\(/g, '\\28')
.replace(/\)/g, '\\29')
.replace(/\0/g, '\\00');
}
/**
* Benutzer in SQLite synchronisieren
*/
@@ -217,6 +230,83 @@ class LDAPService {
);
}
/**
* Benutzer gegen LDAP authentifizieren
*/
static authenticate(username, password, callback) {
// Konfiguration abrufen
this.getConfig((err, config) => {
if (err || !config || !config.enabled) {
return callback(new Error('LDAP ist nicht aktiviert'), false);
}
// LDAP-Verbindung herstellen (mit Service-Account)
this.connect(config, (err, client) => {
if (err) {
return callback(err, false);
}
// Suche nach dem Benutzer in LDAP
const baseDN = config.base_dn || '';
const usernameAttr = config.username_attribute || 'cn';
const escapedUsername = this.escapeLDAPFilter(username);
const searchFilter = `(${usernameAttr}=${escapedUsername})`;
const searchOptions = {
filter: searchFilter,
scope: 'sub',
attributes: ['dn', usernameAttr]
};
let userDN = null;
client.search(baseDN, searchOptions, (err, res) => {
if (err) {
client.unbind();
return callback(err, false);
}
res.on('searchEntry', (entry) => {
userDN = entry.dn.toString();
});
res.on('error', (err) => {
client.unbind();
callback(err, false);
});
res.on('end', (result) => {
// Service-Account-Verbindung schließen
client.unbind();
if (!userDN) {
return callback(new Error('Benutzer nicht gefunden'), false);
}
// Versuche, sich mit den Benutzer-Credentials zu binden
const authClient = ldap.createClient({
url: config.url,
timeout: 10000,
connectTimeout: 10000
});
authClient.on('error', (err) => {
authClient.unbind();
callback(err, false);
});
authClient.bind(userDN, password, (err) => {
authClient.unbind();
if (err) {
return callback(new Error('Ungültiges Passwort'), false);
}
callback(null, true);
});
});
});
});
});
}
/**
* Vollständige Synchronisation durchführen
*/