@immobiliarelabs/backstage-plugin-ldap-auth-backend
Version:
Backstage LDAP Authentication plugin, this packages adds backend authentication and token generation/validation/management; sibling of @immobiliarelabs/backstage-plugin-ldap-auth
127 lines (123 loc) • 3.99 kB
JavaScript
;
var errors = require('@backstage/errors');
var ldapEscape = require('ldap-escape');
var ldapts = require('ldapts');
var errors$1 = require('./errors.cjs.js');
async function createClient(ldapOpts, starttls, bindDn, bindPassword) {
const client = new ldapts.Client({
...ldapOpts,
connectTimeout: ldapOpts.connectTimeout || 5e3
});
if (starttls) await client.startTLS(ldapOpts.tlsOptions);
await client.bind(bindDn, bindPassword);
return client;
}
const defaultCheckUserExists = async (options) => {
const {
ldapOpts,
adminDn,
adminPassword,
username,
userSearchBase,
usernameAttribute = "uid",
starttls
} = options;
const bindDn = adminDn || "";
const bindPassword = adminPassword || "";
try {
const client = await createClient(ldapOpts, starttls, bindDn, bindPassword);
try {
const { searchEntries } = await client.search(userSearchBase || "", {
filter: `(${usernameAttribute}=${username})`,
scope: "sub"
});
return searchEntries.length > 0;
} finally {
if (client.isConnected) await client.unbind();
}
} catch (e) {
throw new Error(
`${errors$1.LDAP_CONNECT_FAIL} ${e instanceof Error ? e.message : String(e)}`
);
}
};
async function defaultLDAPAuthentication(username, password, options) {
const {
ldapOpts,
adminDn,
adminPassword,
userSearchBase,
usernameAttribute = "uid",
starttls
} = options;
let userDn = "";
let foundUser = null;
try {
if (adminDn && adminPassword) {
let adminClient = null;
try {
adminClient = await createClient(
ldapOpts,
starttls,
adminDn,
adminPassword
);
const { searchEntries } = await adminClient.search(
userSearchBase || "",
{
filter: `(${usernameAttribute}=${username})`,
scope: "sub"
}
);
if (searchEntries.length === 0) {
throw new errors.AuthenticationError(errors$1.AUTH_USER_NOT_FOUND);
}
foundUser = searchEntries[0];
userDn = foundUser.dn;
} finally {
if (adminClient?.isConnected) await adminClient.unbind();
}
} else {
userDn = ldapEscape.dn`${usernameAttribute}=${username},` + (userSearchBase || "");
}
let userClient = null;
try {
userClient = await createClient(ldapOpts, starttls, userDn, password);
if (!foundUser && userSearchBase) {
const { searchEntries } = await userClient.search(userSearchBase, {
filter: `(${usernameAttribute}=${username})`,
scope: "sub"
});
if (searchEntries.length > 0) {
foundUser = searchEntries[0];
}
}
} finally {
if (userClient?.isConnected) await userClient.unbind();
}
if (!foundUser) {
throw new errors.AuthenticationError(errors$1.AUTH_USER_NOT_FOUND);
}
const uidVal = foundUser[usernameAttribute];
if (!uidVal) {
throw new errors.AuthenticationError(errors$1.AUTH_USER_DATA_ERROR);
}
return { uid: uidVal };
} catch (e) {
console.error("There was an error when trying to login with ldapts");
if (e && typeof e === "object" && "name" in e && (e.name === "InvalidCredentialsError" || e.name === "NoSuchObjectError")) {
throw new errors.AuthenticationError(errors$1.AUTH_USER_NOT_FOUND);
}
if (e instanceof Error && (e.message.includes(errors$1.AUTH_USER_NOT_FOUND) || e.message.includes(errors$1.AUTH_USER_DATA_ERROR))) {
throw new errors.AuthenticationError(e.message);
}
const error = new Error(
`${errors$1.LDAP_CONNECT_FAIL} ${e instanceof Error ? e.message : String(e)}`
);
error.stack = e instanceof Error ? e.stack : void 0;
throw error;
}
}
exports.defaultCheckUserExists = defaultCheckUserExists;
exports.defaultLDAPAuthentication = defaultLDAPAuthentication;
//# sourceMappingURL=ldap.cjs.js.map