🪪 fix: Preserve SAML NameID Bindings (#15254)
Some checks are pending
Backend Unit Tests / Build packages (push) Waiting to run
Backend Unit Tests / Codegraph select (push) Waiting to run
Backend Unit Tests / TypeScript type checks (push) Blocked by required conditions
Backend Unit Tests / Circular dependency checks (push) Waiting to run
Backend Unit Tests / Tests: api (shard 1/3) (push) Blocked by required conditions
Backend Unit Tests / Tests: api (shard 2/3) (push) Blocked by required conditions
Backend Unit Tests / Tests: api (shard 3/3) (push) Blocked by required conditions
Backend Unit Tests / Tests: data-provider (push) Blocked by required conditions
Backend Unit Tests / Tests: data-schemas (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 1/4) (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 2/4) (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 3/4) (push) Blocked by required conditions
Backend Unit Tests / Tests: @librechat/api (shard 4/4) (push) Blocked by required conditions
Codegraph E2E Votes / vote (full suite) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
Frontend Unit Tests / Codegraph select (push) Waiting to run
Frontend Unit Tests / Build packages (push) Waiting to run
Frontend Unit Tests / TypeScript type checks (client) (push) Blocked by required conditions
Frontend Unit Tests / Tests: @librechat/client (push) Blocked by required conditions
Frontend Unit Tests / Tests: Ubuntu (shard 1/2) (push) Blocked by required conditions
Frontend Unit Tests / Tests: Ubuntu (shard 2/2) (push) Blocked by required conditions
Frontend Unit Tests / Vite build verification (push) Blocked by required conditions
Sync Locize Translations & Create Translation PR / Sync Translation Keys with Locize (push) Waiting to run
Sync Locize Translations & Create Translation PR / Create Translation PR on Version Published (push) Blocked by required conditions

This commit is contained in:
Danny Avila 2026-08-26 10:43:02 -04:00 committed by GitHub
parent 10c2e53c27
commit 2ec222f117
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 27 additions and 0 deletions

View file

@ -216,6 +216,15 @@ function createSamlCallback(existingUsersOnly = false) {
});
}
if (user?.samlId && user.samlId !== profile.nameID) {
logger.warn(
`[samlStrategy] Refused SAML login with a different NameID for user: ${user.email}`,
);
return done(null, false, {
message: ErrorTypes.AUTH_FAILED,
});
}
const appConfig = user?.tenantId
? await resolveAppConfigForUser(getAppConfig, user)
: baseConfig;

View file

@ -7,6 +7,7 @@ jest.mock('@librechat/data-schemas', () => ({
logger: {
info: jest.fn(),
debug: jest.fn(),
warn: jest.fn(),
error: jest.fn(),
},
hashToken: jest.fn().mockResolvedValue('hashed-token'),
@ -426,6 +427,23 @@ u7wlOSk+oFzDIO/UILIA
expect(user.email).toBe(baseProfile.email);
});
it('should reject an email match bound to a different NameID', async () => {
const { findUser, updateUser } = require('~/models');
const existingUser = {
_id: 'existing-user-id',
provider: 'saml',
email: baseProfile.email,
samlId: 'original-name-id',
};
findUser.mockResolvedValueOnce(null).mockResolvedValueOnce(existingUser);
const result = await validate(baseProfile);
expect(result.user).toBe(false);
expect(result.details.message).toBe(require('librechat-data-provider').ErrorTypes.AUTH_FAILED);
expect(updateUser).not.toHaveBeenCalled();
});
it('should block login when email exists with different provider', async () => {
// Set up findUser to return a user with different provider
const { findUser } = require('~/models');