mirror of
https://github.com/danny-avila/LibreChat.git
synced 2025-12-17 08:50:15 +01:00
🛂 fix: OIDC Username Array Edge Case (#2394)
* Patch for OpenID username `username` is generally based on email, rather than `given_name`. The challenge with `given_name` is that it can be a multi-value array (ex: "Nick, Fullname"), which completely breaks the system with: ``` LibreChat | ValidationError: User validation failed: username: Cast to string failed for value "[ 'Nickname', 'Firstname' ]" (type Array) at path "username" LibreChat | at Document.invalidate (/app/node_modules/mongoose/lib/document.js:3200:32) LibreChat | at model.$set (/app/node_modules/mongoose/lib/document.js:1459:12) LibreChat | at model.set [as username] (/app/node_modules/mongoose/lib/helpers/document/compile.js:205:19) LibreChat | at OpenIDConnectStrategy._verify (/app/api/strategies/openidStrategy.js:127:27) LibreChat | at process.processTicksAndRejections (node:internal/process/task_queues:95:5) ``` * Update openidStrategy.js * refactor(openidStrategy): add helper function for stringy username --------- Co-authored-by: Danny Avila <danny@librechat.ai>
This commit is contained in:
parent
9d137ce42f
commit
f380f261a5
1 changed files with 24 additions and 2 deletions
|
|
@ -37,6 +37,26 @@ const downloadImage = async (url, imagePath, accessToken) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an input into a string suitable for a username.
|
||||||
|
* If the input is a string, it will be returned as is.
|
||||||
|
* If the input is an array, elements will be joined with underscores.
|
||||||
|
* In case of undefined or other falsy values, a default value will be returned.
|
||||||
|
*
|
||||||
|
* @param {string | string[] | undefined} input - The input value to be converted into a username.
|
||||||
|
* @param {string} [defaultValue=''] - The default value to return if the input is falsy.
|
||||||
|
* @returns {string} The processed input as a string suitable for a username.
|
||||||
|
*/
|
||||||
|
function convertToUsername(input, defaultValue = '') {
|
||||||
|
if (typeof input === 'string') {
|
||||||
|
return input;
|
||||||
|
} else if (Array.isArray(input)) {
|
||||||
|
return input.join('_');
|
||||||
|
}
|
||||||
|
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
async function setupOpenId() {
|
async function setupOpenId() {
|
||||||
try {
|
try {
|
||||||
const issuer = await Issuer.discover(process.env.OPENID_ISSUER);
|
const issuer = await Issuer.discover(process.env.OPENID_ISSUER);
|
||||||
|
|
@ -104,11 +124,13 @@ async function setupOpenId() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const username = convertToUsername(userinfo.username || userinfo.given_name || userinfo.email);
|
||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
user = new User({
|
user = new User({
|
||||||
provider: 'openid',
|
provider: 'openid',
|
||||||
openidId: userinfo.sub,
|
openidId: userinfo.sub,
|
||||||
username: userinfo.username || userinfo.given_name || '',
|
username,
|
||||||
email: userinfo.email || '',
|
email: userinfo.email || '',
|
||||||
emailVerified: userinfo.email_verified || false,
|
emailVerified: userinfo.email_verified || false,
|
||||||
name: fullName,
|
name: fullName,
|
||||||
|
|
@ -116,7 +138,7 @@ async function setupOpenId() {
|
||||||
} else {
|
} else {
|
||||||
user.provider = 'openid';
|
user.provider = 'openid';
|
||||||
user.openidId = userinfo.sub;
|
user.openidId = userinfo.sub;
|
||||||
user.username = userinfo.username || userinfo.given_name || '';
|
user.username = username;
|
||||||
user.name = fullName;
|
user.name = fullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue