I'm putting together some Node.js code for querying LDAP that uses promises. When I run it, I get Unexpected reserved word concerning the await on line 43. This part:
let connection = await connect(ldapURL).catch((err) => {
console.error('LDAP server error:', err);
reject(err);
});
The entire code is shown below.
I have a promise returned in the connect()
function and that's working fine. In fact, if I remove the promise from the listObjects()
function, the console.debug(results);
line prints exactly what I'm expecting.
So why is the await connect()
causing an error in my listObjects()
function? My searching has yielded a lot of answers saying, "You need to use async," but I already have my listObjects()
declared as async.
Where have I gone wrong?
Full Code:
#!/usr/bin/env node
import ldapjs from 'ldapjs';
const ldapURL = [ 'ldap://127.0.0.1:389' ];
const bindDN = 'uid=search,dc=home';
const bindPassword = 'P@ssw0rd';
function connect(serverURL) {
return new Promise((resolve, reject) => {
const client = ldapjs.createClient({
url: serverURL
});
client.on('connect', () => {
console.debug('Connected to:', ldapURL);
console.debug('Binding as:', bindDN);
client.bind(bindDN, bindPassword, (err) => {
if (err) {
console.debug(err.message);
reject('Bind credentials rejected.');
}
else {
resolve(client);
}
});
});
client.on('error', (err) => {
reject('Unable to connect to ' serverURL);
});
});
}
/**
* Search LDAP and return objects.
* @baseDN {string} Where to start, like 'ou=People,dc=example,dc=com'
* @filter {string} Optional LDAP query to limit results, like '(objectClass=posixAccount)'
* @returns {promise} ... Eventually.
*/
async function listObjects(baseDN, filter) {
return new Promise((resolve, reject) => {
let connection = await connect(ldapURL).catch((err) => {
console.error('LDAP server error:', err);
reject(err);
});
let opts = {
filter: filter,
scope: 'sub'
};
let results = [];
connection.search(`${baseDN}`, opts, (err, res) => {
res.on('searchEntry', (entry) => {
results.push(entry);
});
res.on('end', () => {
connection.unbind(() => {
console.debug(results);
resolve(results);
});
});
});
});
}
let ldapObjects = await listObjects('dc=home', '(objectClass=posixAccount)');
console.log(ldapObjects);
CodePudding user response:
After helpful suggestions in the comments, the solution was to Move the line return new Promise((resolve, reject) => { down so that it only wraps the connection.search(…) part as suggested by Bergi
Here is the code after that modification:
#!/usr/bin/env node
import ldapjs from 'ldapjs';
const ldapURL = [ 'ldap://127.0.0.1:389' ];
const bindDN = 'uid=search,dc=home';
const bindPassword = 'P@ssw0rd';
function connect(serverURL) {
return new Promise((resolve, reject) => {
const client = ldapjs.createClient({
url: serverURL
});
client.on('connect', () => {
console.debug('Connected to:', ldapURL);
console.debug('Binding as:', bindDN);
client.bind(bindDN, bindPassword, (err) => {
if (err) {
console.debug(err.message);
reject('Bind credentials rejected.');
}
else {
resolve(client);
}
});
});
client.on('error', (err) => {
reject('Unable to connect to ' serverURL);
});
});
}
/**
* Search LDAP and return objects.
* @baseDN {string} Where to start, like 'ou=People,dc=example,dc=com'
* @filter {string} Optional LDAP query to limit results, like '(objectClass=posixAccount)'
* @returns {promise} ... Eventually.
*/
async function listObjects(baseDN, filter) {
let connection = await connect(ldapURL).catch((err) => {
console.error('LDAP server error:', err);
reject(err);
});
let opts = {
filter: filter,
scope: 'sub'
};
let results = [];
return new Promise((resolve, reject) => {
connection.search(`${baseDN}`, opts, (err, res) => {
res.on('searchEntry', (entry) => {
results.push(entry);
});
res.on('end', () => {
connection.unbind(() => {
resolve(results);
});
});
});
});
}
let ldapObjects = await listObjects('dc=home', '(objectClass=posixAccount)');
console.log(ldapObjects);
CodePudding user response:
I think you have to remove new Promise because async return the data wraps in the Promise. I think that your ldapObjects store a Promise and listObjects return a Promise wrap inside a Promise.