🆔 fix: Prioritize Immutable Sub Claim for OIDC User ID (#9788)

* add use of immutable claims to identify user object

* fix semicolons

* update email attribute on change

* replace ternary expressions

* fix semicolon

* chore: add typing

* chore: reorder fields in `findOpenIDUser`

* refactor: optimize user lookup logic in `findOpenIDUser` function to minimize database roundtrips

* refactor: integrate findOpenIDUser for improved user retrieval in refreshController

* refactor: improve error logging for invalid refresh tokens in refreshController

* ci: mock findUser correctly in openidStrategy tests

* test: add unit tests for findOpenIDUser function to enhance user retrieval logic

---------

Co-authored-by: Joachim Keltsch <joachim.keltsch@daimlertruck.com>
This commit is contained in:
Danny Avila 2025-09-23 14:46:53 -04:00 committed by GitHub
parent e4f323e71a
commit bcec5bfceb
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 458 additions and 17 deletions

View file

@ -1,4 +1,5 @@
import { logger } from '@librechat/data-schemas';
import { ErrorTypes } from 'librechat-data-provider';
import type { IUser, UserMethods } from '@librechat/data-schemas';
/**
@ -7,16 +8,31 @@ import type { IUser, UserMethods } from '@librechat/data-schemas';
*/
export async function findOpenIDUser({
openidId,
email,
findUser,
email,
idOnTheSource,
strategyName = 'openid',
}: {
openidId: string;
findUser: UserMethods['findUser'];
email?: string;
idOnTheSource?: string;
strategyName?: string;
}): Promise<{ user: IUser | null; error: string | null; migration: boolean }> {
let user = await findUser({ openidId });
const primaryConditions = [];
if (openidId && typeof openidId === 'string') {
primaryConditions.push({ openidId });
}
if (idOnTheSource && typeof idOnTheSource === 'string') {
primaryConditions.push({ idOnTheSource });
}
let user = null;
if (primaryConditions.length > 0) {
user = await findUser({ $or: primaryConditions });
}
if (!user && email) {
user = await findUser({ email });
logger.warn(
@ -28,7 +44,7 @@ export async function findOpenIDUser({
logger.warn(
`[${strategyName}] Attempted OpenID login by user ${user.email}, was registered with "${user.provider}" provider`,
);
return { user: null, error: 'AUTH_FAILED', migration: false };
return { user: null, error: ErrorTypes.AUTH_FAILED, migration: false };
}
// If user found by email but doesn't have openidId, prepare for migration