🛂 feat: Allow LDAP login via username (#3463)

* Allow LDAP login via username

This patch adds the option to login via username instead of using an
email address since the latter may not be unique or may change.

For example, our organization has two main domains and users have a log
and a short form of their mail address. This makes it hard for users to
identify what their primary email address is and causes a lot of
confusion. Using their username instead makes it much easier.

Using a username will also make it easier in the future to not need a
separate bind user to get user attributes. So, this is also a bit of
prep work for that.

* Update config.js

* feat: Enable LDAP login via username

This commit enables the option to login via username instead of using an email address for LDAP authentication. This change is necessary because email addresses may not be unique or may change, causing confusion for users. By using usernames, it becomes easier for users to identify their primary email address. Additionally, this change prepares for future improvements by eliminating the need for a separate bind user to retrieve user attributes.

Co-authored-by: Danny Avila <danny@librechat.ai>

* chore: jsdocs

* chore: import order

* ci: add ldap config tests

---------

Co-authored-by: Lars Kiesow <lkiesow@uos.de>
This commit is contained in:
Danny Avila 2024-07-27 15:42:18 -04:00 committed by GitHub
parent e5dfa06e6c
commit ba9cb71245
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 114 additions and 10 deletions

View file

@ -1,5 +1,6 @@
const express = require('express');
const { CacheKeys, defaultSocialLogins } = require('librechat-data-provider');
const { getLdapConfig } = require('~/server/services/Config/ldap');
const { getProjectByName } = require('~/models/Project');
const { isEnabled } = require('~/server/utils');
const { getLogStores } = require('~/cache');
@ -33,7 +34,8 @@ router.get('/', async function (req, res) {
const instanceProject = await getProjectByName('instance', '_id');
const ldapLoginEnabled = !!process.env.LDAP_URL && !!process.env.LDAP_USER_SEARCH_BASE;
const ldap = getLdapConfig();
try {
/** @type {TStartupConfig} */
const payload = {
@ -51,10 +53,9 @@ router.get('/', async function (req, res) {
!!process.env.OPENID_SESSION_SECRET,
openidLabel: process.env.OPENID_BUTTON_LABEL || 'Continue with OpenID',
openidImageUrl: process.env.OPENID_IMAGE_URL,
ldapLoginEnabled,
serverDomain: process.env.DOMAIN_SERVER || 'http://localhost:3080',
emailLoginEnabled,
registrationEnabled: !ldapLoginEnabled && isEnabled(process.env.ALLOW_REGISTRATION),
registrationEnabled: !ldap?.enabled && isEnabled(process.env.ALLOW_REGISTRATION),
socialLoginEnabled: isEnabled(process.env.ALLOW_SOCIAL_LOGIN),
emailEnabled:
(!!process.env.EMAIL_SERVICE || !!process.env.EMAIL_HOST) &&
@ -76,6 +77,10 @@ router.get('/', async function (req, res) {
instanceProjectId: instanceProject._id.toString(),
};
if (ldap) {
payload.ldap = ldap;
}
if (typeof process.env.CUSTOM_FOOTER === 'string') {
payload.customFooter = process.env.CUSTOM_FOOTER;
}