"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.LDAPProvider = void 0; /** * LDAP/Active Directory authentication provider. */ const ldapjs_1 = __importDefault(require("ldapjs")); class LDAPProvider { constructor(config) { this.config = config; } async authenticate(username, password) { return new Promise((resolve, reject) => { const client = ldapjs_1.default.createClient({ url: this.config.url, tlsOptions: this.config.tlsOptions, }); client.on('error', (err) => { reject(err); }); const escaped = username.replace(/[\\*()\x00]/g, (c) => `\\${c.charCodeAt(0).toString(16).padStart(2, '0')}`); const filter = (this.config.userSearchFilter ?? '(uid={username})') .replace('{username}', escaped); // Bind with service account if provided const bindDN = this.config.bindDN ?? ''; const bindPwd = this.config.bindPassword ?? ''; client.bind(bindDN, bindPwd, (err) => { if (err) { client.destroy(); return resolve(null); } client.search(this.config.baseDN, { filter, scope: 'sub', attributes: ['dn', 'mail', 'displayName', 'memberOf'] }, (searchErr, res) => { if (searchErr) { client.destroy(); return reject(searchErr); } let foundEntry = null; res.on('searchEntry', (entry) => { foundEntry = entry; }); res.on('error', (resErr) => { client.destroy(); reject(resErr); }); res.on('end', () => { if (!foundEntry) { client.destroy(); return resolve(null); } const entry = foundEntry; const userDN = entry.objectName ?? ''; // Authenticate as the found user client.bind(userDN, password, (authErr) => { client.destroy(); if (authErr) { return resolve(null); } const obj = entry.pojo; const getAttr = (name) => { const attr = obj.attributes.find((a) => a.type === name); return attr?.values[0]; }; resolve({ dn: userDN, email: getAttr('mail'), displayName: getAttr('displayName'), groups: obj.attributes .find((a) => a.type === 'memberOf') ?.values ?? [], }); }); }); }); }); }); } } exports.LDAPProvider = LDAPProvider;