🔒 fix: Email Domain Validation Order and Coverage (#9566)

This commit is contained in:
Danny Avila 2025-09-10 23:13:39 -04:00 committed by GitHub
parent 85aa3e7d9c
commit 5676976564
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 69 additions and 15 deletions

View file

@ -4,6 +4,7 @@ const { logger } = require('@librechat/data-schemas');
const { isEnabled, getBalanceConfig } = require('@librechat/api');
const { SystemRoles, ErrorTypes } = require('librechat-data-provider');
const { createUser, findUser, updateUser, countUsers } = require('~/models');
const { isEmailDomainAllowed } = require('~/server/services/domains');
const { getAppConfig } = require('~/server/services/Config');
const {
@ -124,6 +125,15 @@ const ldapLogin = new LdapStrategy(ldapOptions, async (userinfo, done) => {
if (!user) {
const isFirstRegisteredUser = (await countUsers()) === 0;
const role = isFirstRegisteredUser ? SystemRoles.ADMIN : SystemRoles.USER;
const appConfig = await getAppConfig({ role });
if (!isEmailDomainAllowed(mail, appConfig?.registration?.allowedDomains)) {
logger.error(
`[LDAP Strategy] Registration blocked - email domain not allowed [Email: ${mail}]`,
);
return done(null, false, { message: 'Email domain not allowed for registration' });
}
user = {
provider: 'ldap',
ldapId,
@ -133,7 +143,6 @@ const ldapLogin = new LdapStrategy(ldapOptions, async (userinfo, done) => {
name: fullName,
role,
};
const appConfig = await getAppConfig({ role: user?.role });
const balanceConfig = getBalanceConfig(appConfig);
const userId = await createUser(user, balanceConfig);
user._id = userId;

View file

@ -15,6 +15,7 @@ const {
getBalanceConfig,
} = require('@librechat/api');
const { getStrategyFunctions } = require('~/server/services/Files/strategies');
const { isEmailDomainAllowed } = require('~/server/services/domains');
const { findUser, createUser, updateUser } = require('~/models');
const { getAppConfig } = require('~/server/services/Config');
const getLogStores = require('~/cache/getLogStores');
@ -400,6 +401,13 @@ async function setupOpenId() {
const appConfig = await getAppConfig();
if (!user) {
if (!isEmailDomainAllowed(userinfo.email, appConfig?.registration?.allowedDomains)) {
logger.error(
`[OpenID Strategy] Registration blocked - email domain not allowed [Email: ${userinfo.email}]`,
);
return done(null, false, { message: 'Email domain not allowed for registration' });
}
user = {
provider: 'openid',
openidId: userinfo.sub,

View file

@ -7,6 +7,7 @@ const { ErrorTypes } = require('librechat-data-provider');
const { hashToken, logger } = require('@librechat/data-schemas');
const { Strategy: SamlStrategy } = require('@node-saml/passport-saml');
const { getStrategyFunctions } = require('~/server/services/Files/strategies');
const { isEmailDomainAllowed } = require('~/server/services/domains');
const { findUser, createUser, updateUser } = require('~/models');
const { getAppConfig } = require('~/server/services/Config');
const paths = require('~/config/paths');
@ -222,11 +223,19 @@ async function setupSaml() {
const appConfig = await getAppConfig();
if (!user) {
const userEmail = getEmail(profile) || '';
if (!isEmailDomainAllowed(userEmail, appConfig?.registration?.allowedDomains)) {
logger.error(
`[SAML Strategy] Registration blocked - email domain not allowed [Email: ${userEmail}]`,
);
return done(null, false, { message: 'Email domain not allowed for registration' });
}
user = {
provider: 'saml',
samlId: profile.nameID,
username,
email: getEmail(profile) || '',
email: userEmail,
emailVerified: true,
name: fullName,
};

View file

@ -2,6 +2,7 @@ const { isEnabled } = require('@librechat/api');
const { logger } = require('@librechat/data-schemas');
const { ErrorTypes } = require('librechat-data-provider');
const { createSocialUser, handleExistingUser } = require('./process');
const { isEmailDomainAllowed } = require('~/server/services/domains');
const { getAppConfig } = require('~/server/services/Config');
const { findUser } = require('~/models');
@ -17,6 +18,16 @@ const socialLogin =
const existingUser = await findUser({ email: email.trim() });
const ALLOW_SOCIAL_REGISTRATION = isEnabled(process.env.ALLOW_SOCIAL_REGISTRATION);
if (!existingUser && !isEmailDomainAllowed(email, appConfig?.registration?.allowedDomains)) {
logger.error(
`[${provider}Login] Registration blocked - email domain not allowed [Email: ${email}]`,
);
const error = new Error(ErrorTypes.AUTH_FAILED);
error.code = ErrorTypes.AUTH_FAILED;
error.message = 'Email domain not allowed for registration';
return cb(error);
}
if (existingUser?.provider === provider) {
await handleExistingUser(existingUser, avatarUrl, appConfig);
return cb(null, existingUser);