| const cookies = require('cookie'); |
| const jwksRsa = require('jwks-rsa'); |
| const { logger } = require('@librechat/data-schemas'); |
| const { HttpsProxyAgent } = require('https-proxy-agent'); |
| const { SystemRoles } = require('librechat-data-provider'); |
| const { Strategy: JwtStrategy, ExtractJwt } = require('passport-jwt'); |
| const { isEnabled, findOpenIDUser } = require('@librechat/api'); |
| const { updateUser, findUser } = require('~/models'); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| const openIdJwtLogin = (openIdConfig) => { |
| let jwksRsaOptions = { |
| cache: isEnabled(process.env.OPENID_JWKS_URL_CACHE_ENABLED) || true, |
| cacheMaxAge: process.env.OPENID_JWKS_URL_CACHE_TIME |
| ? eval(process.env.OPENID_JWKS_URL_CACHE_TIME) |
| : 60000, |
| jwksUri: openIdConfig.serverMetadata().jwks_uri, |
| }; |
|
|
| if (process.env.PROXY) { |
| jwksRsaOptions.requestAgent = new HttpsProxyAgent(process.env.PROXY); |
| } |
|
|
| return new JwtStrategy( |
| { |
| jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), |
| secretOrKeyProvider: jwksRsa.passportJwtSecret(jwksRsaOptions), |
| passReqToCallback: true, |
| }, |
| |
| |
| |
| |
| |
| async (req, payload, done) => { |
| try { |
| const authHeader = req.headers.authorization; |
| const rawToken = authHeader?.replace('Bearer ', ''); |
|
|
| const { user, error, migration } = await findOpenIDUser({ |
| findUser, |
| email: payload?.email, |
| openidId: payload?.sub, |
| idOnTheSource: payload?.oid, |
| strategyName: 'openIdJwtLogin', |
| }); |
|
|
| if (error) { |
| done(null, false, { message: error }); |
| return; |
| } |
|
|
| if (user) { |
| user.id = user._id.toString(); |
|
|
| const updateData = {}; |
| if (migration) { |
| updateData.provider = 'openid'; |
| updateData.openidId = payload?.sub; |
| } |
| if (!user.role) { |
| user.role = SystemRoles.USER; |
| updateData.role = user.role; |
| } |
|
|
| if (Object.keys(updateData).length > 0) { |
| await updateUser(user.id, updateData); |
| } |
|
|
| const cookieHeader = req.headers.cookie; |
| const parsedCookies = cookieHeader ? cookies.parse(cookieHeader) : {}; |
| const accessToken = parsedCookies.openid_access_token; |
| const refreshToken = parsedCookies.refreshToken; |
|
|
| user.federatedTokens = { |
| access_token: accessToken || rawToken, |
| id_token: rawToken, |
| refresh_token: refreshToken, |
| expires_at: payload.exp, |
| }; |
|
|
| done(null, user); |
| } else { |
| logger.warn( |
| '[openIdJwtLogin] openId JwtStrategy => no user found with the sub claims: ' + |
| payload?.sub + |
| (payload?.email ? ' or email: ' + payload.email : ''), |
| ); |
| done(null, false); |
| } |
| } catch (err) { |
| done(err, false); |
| } |
| }, |
| ); |
| }; |
|
|
| module.exports = openIdJwtLogin; |
|
|