Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix+feat: fix infinte-loading due to non-call of callback and expose error message into frontend #2516

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
53 changes: 33 additions & 20 deletions api/server/routes/oauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@ const domains = {

router.use(loginLimiter);

const authenticate = (strategy, options) => {
return (req, res, next) =>
passport.authenticate(strategy, options, (err, user, info) => {
if (err) {
return next(err);
}

if (user) {
req.user = user;
}

if (!user && info) {
const message = info.message || info;
if (typeof message === 'string') {
return res.redirect(`${domains.client}/login?error=${message}`);
}
}

next();
})(req, res, next);
};

const oauthHandler = async (req, res) => {
try {
await checkDomainAllowed(req, res);
Expand All @@ -33,17 +55,15 @@ const oauthHandler = async (req, res) => {
*/
router.get(
'/google',
passport.authenticate('google', {
authenticate('google', {
scope: ['openid', 'profile', 'email'],
session: false,
}),
);

router.get(
'/google/callback',
passport.authenticate('google', {
failureRedirect: `${domains.client}/login`,
failureMessage: true,
authenticate('google', {
session: false,
scope: ['openid', 'profile', 'email'],
}),
Expand All @@ -52,7 +72,7 @@ router.get(

router.get(
'/facebook',
passport.authenticate('facebook', {
authenticate('facebook', {
scope: ['public_profile'],
profileFields: ['id', 'email', 'name'],
session: false,
Expand All @@ -61,9 +81,7 @@ router.get(

router.get(
'/facebook/callback',
passport.authenticate('facebook', {
failureRedirect: `${domains.client}/login`,
failureMessage: true,
authenticate('facebook', {
session: false,
scope: ['public_profile'],
profileFields: ['id', 'email', 'name'],
Expand All @@ -73,52 +91,47 @@ router.get(

router.get(
'/openid',
passport.authenticate('openid', {
authenticate('openid', {
session: false,
}),
);

router.get(
'/openid/callback',
passport.authenticate('openid', {
failureRedirect: `${domains.client}/login`,
failureMessage: true,
authenticate('openid', {
session: false,
}),
oauthHandler,
);

router.get(
'/github',
passport.authenticate('github', {
authenticate('github', {
scope: ['user:email', 'read:user'],
session: false,
}),
);

router.get(
'/github/callback',
passport.authenticate('github', {
failureRedirect: `${domains.client}/login`,
failureMessage: true,
authenticate('github', {
session: false,
scope: ['user:email', 'read:user'],
}),
oauthHandler,
);

router.get(
'/discord',
passport.authenticate('discord', {
authenticate('discord', {
scope: ['identify', 'email'],
session: false,
}),
);

router.get(
'/discord/callback',
passport.authenticate('discord', {
failureRedirect: `${domains.client}/login`,
failureMessage: true,
authenticate('discord', {
session: false,
scope: ['identify', 'email'],
}),
Expand Down
24 changes: 13 additions & 11 deletions api/strategies/discordStrategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,20 @@ const discordLogin = async (accessToken, refreshToken, profile, cb) => {
return cb(null, oldUser);
}

if (ALLOW_SOCIAL_REGISTRATION) {
const newUser = await createNewUser({
email,
avatarUrl,
provider: 'discord',
providerKey: 'discordId',
providerId: discordId,
username: profile.username,
name: profile.global_name,
});
return cb(null, newUser);
if (!ALLOW_SOCIAL_REGISTRATION) {
return cb(null, false, { message: 'Social signup is disabled.' });
}

const newUser = await createNewUser({
email,
avatarUrl,
provider: 'discord',
providerKey: 'discordId',
providerId: discordId,
username: profile.username,
name: profile.global_name,
});
return cb(null, newUser);
} catch (err) {
logger.error('[discordLogin]', err);
return cb(err);
Expand Down
24 changes: 13 additions & 11 deletions api/strategies/facebookStrategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ const facebookLogin = async (accessToken, refreshToken, profile, cb) => {
return cb(null, oldUser);
}

if (ALLOW_SOCIAL_REGISTRATION) {
const newUser = await createNewUser({
email,
avatarUrl,
provider: 'facebook',
providerKey: 'facebookId',
providerId: facebookId,
username: profile.displayName,
name: profile.name?.givenName + ' ' + profile.name?.familyName,
});
return cb(null, newUser);
if (!ALLOW_SOCIAL_REGISTRATION) {
return cb(null, false, { message: 'Social signup is disabled.' });
}

const newUser = await createNewUser({
email,
avatarUrl,
provider: 'facebook',
providerKey: 'facebookId',
providerId: facebookId,
username: profile.displayName,
name: profile.name?.givenName + ' ' + profile.name?.familyName,
});
return cb(null, newUser);
} catch (err) {
logger.error('[facebookLogin]', err);
return cb(err);
Expand Down
26 changes: 14 additions & 12 deletions api/strategies/githubStrategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@ const githubLogin = async (accessToken, refreshToken, profile, cb) => {
return cb(null, oldUser);
}

if (ALLOW_SOCIAL_REGISTRATION) {
const newUser = await createNewUser({
email,
avatarUrl,
provider: 'github',
providerKey: 'githubId',
providerId: githubId,
username: profile.username,
name: profile.displayName,
emailVerified: profile.emails[0].verified,
});
return cb(null, newUser);
if (!ALLOW_SOCIAL_REGISTRATION) {
return cb(null, false, { message: 'Social signup is disabled.' });
}

const newUser = await createNewUser({
email,
avatarUrl,
provider: 'github',
providerKey: 'githubId',
providerId: githubId,
username: profile.username,
name: profile.displayName,
emailVerified: profile.emails[0].verified,
});
return cb(null, newUser);
} catch (err) {
logger.error('[githubLogin]', err);
return cb(err);
Expand Down
26 changes: 14 additions & 12 deletions api/strategies/googleStrategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@ const googleLogin = async (accessToken, refreshToken, profile, cb) => {
return cb(null, oldUser);
}

if (ALLOW_SOCIAL_REGISTRATION) {
const newUser = await createNewUser({
email,
avatarUrl,
provider: 'google',
providerKey: 'googleId',
providerId: googleId,
username: profile.name.givenName,
name: `${profile.name.givenName} ${profile.name.familyName}`,
emailVerified: profile.emails[0].verified,
});
return cb(null, newUser);
if (!ALLOW_SOCIAL_REGISTRATION) {
return cb(null, false, { message: 'Social signup is disabled.' });
}

const newUser = await createNewUser({
email,
avatarUrl,
provider: 'google',
providerKey: 'googleId',
providerId: googleId,
username: profile.name.givenName,
name: `${profile.name.givenName} ${profile.name.familyName}`,
emailVerified: profile.emails[0].verified,
});
return cb(null, newUser);
} catch (err) {
logger.error('[googleLogin]', err);
return cb(err);
Expand Down
20 changes: 19 additions & 1 deletion client/src/components/Auth/Login.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
import { GoogleIcon, FacebookIcon, OpenIDIcon, GithubIcon, DiscordIcon } from '~/components';
Expand All @@ -15,12 +15,22 @@ function Login() {
const localize = useLocalize();
const navigate = useNavigate();

const [customError, setCustomError] = useState<string | undefined>(undefined);

useEffect(() => {
if (isAuthenticated) {
navigate('/c/new', { replace: true });
}
}, [isAuthenticated, navigate]);

useEffect(() => {
if (window?.location?.search?.includes('error')) {
const errorParam = new URLSearchParams(window.location.search).get('error');
if (errorParam) {
setCustomError(errorParam);
}
}
}, []);
if (!startupConfig) {
return null;
}
Expand Down Expand Up @@ -140,6 +150,14 @@ function Login() {
{localize(getLoginError(error))}
</div>
)}
{customError && (
<div
className="my-4 rounded-md border border-red-500 bg-red-500/10 px-3 py-2 text-sm text-gray-600 dark:text-gray-200"
role="alert"
>
{customError}
</div>
)}
{startupConfig.emailLoginEnabled && <LoginForm onSubmit={login} />}
{startupConfig.registrationEnabled && (
<p className="my-4 text-center text-sm font-light text-gray-700 dark:text-white">
Expand Down