Handle unset optional LDAP user search filter

An unset LDAP_USER_SEARCH_FILTER was indexed after service-account binding, causing the reported undefined index TypeError instead of searching users. Preserve configured filters and reject invalid types explicitly.

Thanks to Nissulya and xet7 !

Fixes #6692,
This commit is contained in:
Lauri Ojansivu committed 2026-09-14 13:52:37 +03:00
1 parent 5b2ce8f6f3
commit 2c5cdd78a9
2 files changed
+24 -1

No files matched your search

+7 -1
View File
@@ -369,7 +369,13 @@ export default class LDAP {
getUserFilter(username) {
const filter = [];
if (this.options.User_Search_Filter !== '') {
// The optional filter may be unset, especially in snap configurations.
// Binding succeeds before this method runs; indexing undefined made the
// subsequent search look like a bind failure (#6692).
if (this.options.User_Search_Filter != null && this.options.User_Search_Filter !== '') {
if (typeof this.options.User_Search_Filter !== 'string') {
throw new Error('LDAP_USER_SEARCH_FILTER must be a string');
}
if (this.options.User_Search_Filter[0] === '(') {
filter.push(`${this.options.User_Search_Filter}`);
} else {
+17
View File
@@ -0,0 +1,17 @@
'use strict';
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const source = fs.readFileSync(path.join(__dirname, '../packages/wekan-ldap/server/ldap.js'), 'utf8');
const body = source.split(' getUserFilter(username) {')[1].split('\n async bindUserIfNecessary')[0].replace(/\n }\s*$/, '');
const getUserFilter = new Function('escapedToHex', 'Log', `return function(username) {${body}}`)(value => value, { error() {} });
for (const value of [undefined, null, '']) {
assert.equal(getUserFilter.call({ options: { User_Search_Filter: value, User_Search_Field: 'sAMAccountName' } }, 'alice'), '(&(sAMAccountName=alice))');
}
for (const value of ['objectClass=person', '(objectClass=person)']) {
assert.equal(getUserFilter.call({ options: { User_Search_Filter: value, User_Search_Field: 'uid,mail' } }, 'alice'), '(&(objectClass=person)(|(uid=alice)(mail=alice)))');
}
for (const value of [true, 123, {}]) {
assert.throws(() => getUserFilter.call({ options: { User_Search_Filter: value, User_Search_Field: 'uid' } }, 'alice'), /LDAP_USER_SEARCH_FILTER must be a string/);
}
console.log('ldapOptionalUserFilter: unset optional filter, configured restrictions and invalid-type failures verified');