/** * AD/LDAP routes module. */ const express = require('express'); const { authMiddleware, adminMiddleware } = require('../middleware/auth'); const { auditLog } = require('../auditLog'); const { isLDAPConfigured } = require('../ldapSync'); const { browseOUTree, createADUser, checkADUserExists, deleteADUser } = require('../ldapOperations'); const { searchADGroups, addUserToGroups, browseADGroups } = require('../ldapOperations'); const { validate, createADUserSchema, deleteADUserSchema } = require('../middleware/validation'); const router = express.Router(); // LDAP Status Endpoint (public) router.get('/status', (req, res) => { res.json({ configured: isLDAPConfigured() }); }); // All other AD routes require auth router.use(authMiddleware); // Browse OU tree router.get('/ou-tree', (req, res) => { const { base } = req.query; browseOUTree(base || undefined).then(ous => { res.json(ous); }).catch(err => { console.error('[ERROR] GET /ad/ou-tree -', err.message); res.status(500).json({ error: 'Interner Serverfehler.' }); }); }); // Search AD groups (all security groups) router.get('/groups', (req, res) => { const { q } = req.query; if (!q || q.trim().length < 2) { return res.json([]); } searchADGroups(q.trim()).then(groups => { res.json(groups); }).catch(err => { console.error('[ERROR] GET /ad/groups -', err.message); res.status(500).json({ error: 'Interner Serverfehler.' }); }); }); // Browse all AD groups (for tree display) router.get('/groups-tree', (req, res) => { browseADGroups().then(groups => { res.json(groups); }).catch(err => { console.error('[ERROR] GET /ad/groups-tree -', err.message); res.status(500).json({ error: 'Interner Serverfehler.' }); }); }); // Get AD create config router.get('/create-config', (req, res) => { res.json({ configured: isLDAPConfigured(), createOU: process.env.LDAP_CREATE_OU || '', upnSuffix: process.env.LDAP_UPN_SUFFIX || process.env.LDAP_BIND_USER?.split('@')[1] || '', }); }); // Create AD user (admin only) router.post('/create-user', adminMiddleware, validate(createADUserSchema), async (req, res) => { const { ou, vorname, nachname, email, username, password, department, telefon, titel, displayName, physicalDeliveryOfficeName, company, description, wWWHomePage, streetAddress, postOfficeBox, l, st, postalCode, c, groups } = req.validatedBody; try { let sAMAccountName = username; if (vorname && nachname) { sAMAccountName = nachname.replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue') .replace(/Ä/g, 'Ae').replace(/Ö/g, 'Oe').replace(/Ü/g, 'Ue').replace(/ß/g, 'ss') + vorname.charAt(0).replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue') .replace(/Ä/g, 'Ae').replace(/Ö/g, 'Oe').replace(/Ü/g, 'Ue').replace(/ß/g, 'ss'); sAMAccountName = sAMAccountName.replace(/[^a-zA-Z0-9]/g, '').substring(0, 20); } const existing = await checkADUserExists(username, sAMAccountName); if (existing) { return res.status(409).json({ error: 'Benutzername "' + username + '" existiert bereits im Active Directory.', dn: existing.distinguishedName }); } const result = await createADUser({ ou, vorname, nachname, email, username, password, department, telefon, titel, displayName, physicalDeliveryOfficeName, company, description, wWWHomePage, streetAddress, postOfficeBox, l, st, postalCode, c }); if (result.warning && result.dn) { auditLog(req.user?.id, 'ad.create-user', 'ad_user', null, `AD user created with warning: ${username} - ${result.warning}`); } else { auditLog(req.user?.id, 'ad.create-user', 'ad_user', null, `Created AD user: ${username}`); } // Add user to groups if specified let groupResults = []; if (groups && Array.isArray(groups) && groups.length > 0 && result.dn) { try { groupResults = await addUserToGroups(result.dn, groups); const addedCount = groupResults.filter(r => r.status === 'added').length; auditLog(req.user?.id, 'ad.create-user', 'ad_user', null, `Added ${username} to ${addedCount} group(s)`); } catch (groupErr) { console.error('[WARN] Gruppenzuweisung fehlgeschlagen:', groupErr.message); groupResults = groups.map(dn => ({ dn, status: 'error', error: groupErr.message })); } } res.status(201).json({ ...result, groupResults }); } catch (err) { auditLog(req.user?.id, 'ad.create-user-failed', 'ad_user', null, `Failed to create AD user: ${username} - ${err.message}`); res.status(500).json({ error: 'Interner Serverfehler.' }); } }); // Delete AD user (admin only) router.delete('/delete-user', adminMiddleware, validate(deleteADUserSchema), async (req, res) => { const { dn } = req.validatedBody; try { await deleteADUser(dn); auditLog(req.user?.id, 'ad.delete-user', 'ad_user', null, `Deleted AD user: ${dn}`); res.json({ success: true, message: 'Benutzer erfolgreich gelöscht.' }); } catch (err) { res.status(500).json({ error: 'Fehler beim Löschen des AD-Benutzers: ' + err.message }); } }); module.exports = router;