| | |
| | const express = require('express'); |
| | const passport = require('passport'); |
| | const { randomState } = require('openid-client'); |
| | const { logger } = require('@librechat/data-schemas'); |
| | const { ErrorTypes } = require('librechat-data-provider'); |
| | const { isEnabled, createSetBalanceConfig } = require('@librechat/api'); |
| | const { checkDomainAllowed, loginLimiter, logHeaders, checkBan } = require('~/server/middleware'); |
| | const { syncUserEntraGroupMemberships } = require('~/server/services/PermissionService'); |
| | const { setAuthTokens, setOpenIDAuthTokens } = require('~/server/services/AuthService'); |
| | const { getAppConfig } = require('~/server/services/Config'); |
| | const { Balance } = require('~/db/models'); |
| |
|
| | const setBalanceConfig = createSetBalanceConfig({ |
| | getAppConfig, |
| | Balance, |
| | }); |
| |
|
| | const router = express.Router(); |
| |
|
| | const domains = { |
| | client: process.env.DOMAIN_CLIENT, |
| | server: process.env.DOMAIN_SERVER, |
| | }; |
| |
|
| | router.use(logHeaders); |
| | router.use(loginLimiter); |
| |
|
| | const oauthHandler = async (req, res, next) => { |
| | try { |
| | if (res.headersSent) { |
| | return; |
| | } |
| |
|
| | await checkBan(req, res); |
| | if (req.banned) { |
| | return; |
| | } |
| | if ( |
| | req.user && |
| | req.user.provider == 'openid' && |
| | isEnabled(process.env.OPENID_REUSE_TOKENS) === true |
| | ) { |
| | await syncUserEntraGroupMemberships(req.user, req.user.tokenset.access_token); |
| | setOpenIDAuthTokens(req.user.tokenset, res, req.user._id.toString()); |
| | } else { |
| | await setAuthTokens(req.user._id, res); |
| | } |
| | res.redirect(domains.client); |
| | } catch (err) { |
| | logger.error('Error in setting authentication tokens:', err); |
| | next(err); |
| | } |
| | }; |
| |
|
| | router.get('/error', (req, res) => { |
| | |
| | const errorMessage = req.session?.messages?.pop() || 'Unknown error'; |
| | logger.error('Error in OAuth authentication:', { |
| | message: errorMessage, |
| | }); |
| |
|
| | res.redirect(`${domains.client}/login?redirect=false&error=${ErrorTypes.AUTH_FAILED}`); |
| | }); |
| |
|
| | |
| | |
| | |
| | router.get( |
| | '/google', |
| | passport.authenticate('google', { |
| | scope: ['openid', 'profile', 'email'], |
| | session: false, |
| | }), |
| | ); |
| |
|
| | router.get( |
| | '/google/callback', |
| | passport.authenticate('google', { |
| | failureRedirect: `${domains.client}/oauth/error`, |
| | failureMessage: true, |
| | session: false, |
| | scope: ['openid', 'profile', 'email'], |
| | }), |
| | setBalanceConfig, |
| | checkDomainAllowed, |
| | oauthHandler, |
| | ); |
| |
|
| | |
| | |
| | |
| | router.get( |
| | '/facebook', |
| | passport.authenticate('facebook', { |
| | scope: ['public_profile'], |
| | profileFields: ['id', 'email', 'name'], |
| | session: false, |
| | }), |
| | ); |
| |
|
| | router.get( |
| | '/facebook/callback', |
| | passport.authenticate('facebook', { |
| | failureRedirect: `${domains.client}/oauth/error`, |
| | failureMessage: true, |
| | session: false, |
| | scope: ['public_profile'], |
| | profileFields: ['id', 'email', 'name'], |
| | }), |
| | setBalanceConfig, |
| | checkDomainAllowed, |
| | oauthHandler, |
| | ); |
| |
|
| | |
| | |
| | |
| | router.get('/openid', (req, res, next) => { |
| | return passport.authenticate('openid', { |
| | session: false, |
| | state: randomState(), |
| | })(req, res, next); |
| | }); |
| |
|
| | router.get( |
| | '/openid/callback', |
| | passport.authenticate('openid', { |
| | failureRedirect: `${domains.client}/oauth/error`, |
| | failureMessage: true, |
| | session: false, |
| | }), |
| | setBalanceConfig, |
| | checkDomainAllowed, |
| | oauthHandler, |
| | ); |
| |
|
| | |
| | |
| | |
| | router.get( |
| | '/github', |
| | passport.authenticate('github', { |
| | scope: ['user:email', 'read:user'], |
| | session: false, |
| | }), |
| | ); |
| |
|
| | router.get( |
| | '/github/callback', |
| | passport.authenticate('github', { |
| | failureRedirect: `${domains.client}/oauth/error`, |
| | failureMessage: true, |
| | session: false, |
| | scope: ['user:email', 'read:user'], |
| | }), |
| | setBalanceConfig, |
| | checkDomainAllowed, |
| | oauthHandler, |
| | ); |
| |
|
| | |
| | |
| | |
| | router.get( |
| | '/discord', |
| | passport.authenticate('discord', { |
| | scope: ['identify', 'email'], |
| | session: false, |
| | }), |
| | ); |
| |
|
| | router.get( |
| | '/discord/callback', |
| | passport.authenticate('discord', { |
| | failureRedirect: `${domains.client}/oauth/error`, |
| | failureMessage: true, |
| | session: false, |
| | scope: ['identify', 'email'], |
| | }), |
| | setBalanceConfig, |
| | checkDomainAllowed, |
| | oauthHandler, |
| | ); |
| |
|
| | |
| | |
| | |
| | router.get( |
| | '/apple', |
| | passport.authenticate('apple', { |
| | session: false, |
| | }), |
| | ); |
| |
|
| | router.post( |
| | '/apple/callback', |
| | passport.authenticate('apple', { |
| | failureRedirect: `${domains.client}/oauth/error`, |
| | failureMessage: true, |
| | session: false, |
| | }), |
| | setBalanceConfig, |
| | checkDomainAllowed, |
| | oauthHandler, |
| | ); |
| |
|
| | |
| | |
| | |
| | router.get( |
| | '/saml', |
| | passport.authenticate('saml', { |
| | session: false, |
| | }), |
| | ); |
| |
|
| | router.post( |
| | '/saml/callback', |
| | passport.authenticate('saml', { |
| | failureRedirect: `${domains.client}/oauth/error`, |
| | failureMessage: true, |
| | session: false, |
| | }), |
| | oauthHandler, |
| | ); |
| |
|
| | module.exports = router; |
| |
|