feat: facebook login (#820)

* Facebook strategy

* Update user_auth_system.md

* Update user_auth_system.md
This commit is contained in:
Marco Beretta 2023-08-25 02:10:48 +02:00 committed by GitHub
parent a569020312
commit 007d51ede1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 155 additions and 27 deletions

View file

@ -4,7 +4,7 @@ import { useAuthContext } from '~/hooks/AuthContext';
import { useNavigate } from 'react-router-dom';
import { useLocalize } from '~/hooks';
import { useGetStartupConfig } from 'librechat-data-provider';
import { GoogleIcon, OpenIDIcon, GithubIcon, DiscordIcon } from '~/components';
import { GoogleIcon, FacebookIcon, OpenIDIcon, GithubIcon, DiscordIcon } from '~/components';
function Login() {
const { login, error, isAuthenticated } = useAuthContext();
@ -65,6 +65,20 @@ function Login() {
</div>
</>
)}
{startupConfig?.facebookLoginEnabled && startupConfig?.socialLoginEnabled && (
<>
<div className="mt-2 flex gap-x-2">
<a
aria-label="Login with Facebook"
className="justify-left flex w-full items-center space-x-3 rounded-md border border-gray-300 px-5 py-3 hover:bg-gray-50 focus:ring-2 focus:ring-violet-600 focus:ring-offset-1"
href={`${startupConfig.serverDomain}/oauth/facebook`}
>
<FacebookIcon />
<p>{localize('com_auth_facebook_login')}</p>
</a>
</div>
</>
)}
{startupConfig?.openidLoginEnabled && startupConfig?.socialLoginEnabled && (
<>
<div className="mt-2 flex gap-x-2">

View file

@ -7,7 +7,7 @@ import {
TRegisterUser,
useGetStartupConfig,
} from 'librechat-data-provider';
import { GoogleIcon, OpenIDIcon, GithubIcon, DiscordIcon } from '~/components';
import { GoogleIcon, FacebookIcon, OpenIDIcon, GithubIcon, DiscordIcon } from '~/components';
function Registration() {
const navigate = useNavigate();
@ -308,6 +308,20 @@ function Registration() {
</div>
</>
)}
{startupConfig?.facebookLoginEnabled && startupConfig?.socialLoginEnabled && (
<>
<div className="mt-2 flex gap-x-2">
<a
aria-label="Login with Facebook"
className="justify-left flex w-full items-center space-x-3 rounded-md border border-gray-300 px-5 py-3 hover:bg-gray-50 focus:ring-2 focus:ring-violet-600 focus:ring-offset-1"
href={`${startupConfig.serverDomain}/oauth/facebook`}
>
<FacebookIcon />
<p>{localize('com_auth_facebook_login')}</p>
</a>
</div>
</>
)}
{startupConfig?.openidLoginEnabled && startupConfig?.socialLoginEnabled && (
<>
<div className="mt-2 flex gap-x-2">

View file

@ -23,6 +23,7 @@ const setup = ({
isError: false,
data: {
googleLoginEnabled: true,
facebookLoginEnabled: true,
openidLoginEnabled: true,
openidLabel: 'Test OpenID',
openidImageUrl: 'http://test-server.com',
@ -67,6 +68,21 @@ test('renders login form', () => {
'href',
'mock-server/oauth/google',
);
expect(getByRole('link', { name: /Login with Facebook/i })).toBeInTheDocument();
expect(getByRole('link', { name: /Login with Facebook/i })).toHaveAttribute(
'href',
'mock-server/oauth/facebook',
);
expect(getByRole('link', { name: /Login with Github/i })).toBeInTheDocument();
expect(getByRole('link', { name: /Login with Github/i })).toHaveAttribute(
'href',
'mock-server/oauth/github',
);
expect(getByRole('link', { name: /Login with Discord/i })).toBeInTheDocument();
expect(getByRole('link', { name: /Login with Discord/i })).toHaveAttribute(
'href',
'mock-server/oauth/discord',
);
});
test('calls loginUser.mutate on login', async () => {

View file

@ -24,6 +24,7 @@ const setup = ({
isError: false,
data: {
googleLoginEnabled: true,
facebookLoginEnabled: true,
openidLoginEnabled: true,
openidLabel: 'Test OpenID',
openidImageUrl: 'http://test-server.com',
@ -75,6 +76,21 @@ test('renders registration form', () => {
'href',
'mock-server/oauth/google',
);
expect(getByRole('link', { name: /Login with Facebook/i })).toBeInTheDocument();
expect(getByRole('link', { name: /Login with Facebook/i })).toHaveAttribute(
'href',
'mock-server/oauth/facebook',
);
expect(getByRole('link', { name: /Login with Github/i })).toBeInTheDocument();
expect(getByRole('link', { name: /Login with Github/i })).toHaveAttribute(
'href',
'mock-server/oauth/github',
);
expect(getByRole('link', { name: /Login with Discord/i })).toBeInTheDocument();
expect(getByRole('link', { name: /Login with Discord/i })).toHaveAttribute(
'href',
'mock-server/oauth/discord',
);
});
// eslint-disable-next-line jest/no-commented-out-tests

View file

@ -0,0 +1,28 @@
import React from 'react';
export default function FacebookIcon() {
return (
<svg viewBox="0 0 40 40" width="25" height="25">
<linearGradient
id="a"
x1={-277.375}
x2={-277.375}
y1={406.602}
y2={407.573}
gradientTransform="matrix(40 0 0 -39.7778 11115.001 16212.334)"
gradientUnits="userSpaceOnUse"
>
<stop offset={0} stopColor="#0062e0" />
<stop offset={1} stopColor="#19afff" />
</linearGradient>
<path
fill="url(#a)"
d="M16.7 39.8C7.2 38.1 0 29.9 0 20 0 9 9 0 20 0s20 9 20 20c0 9.9-7.2 18.1-16.7 19.8l-1.1-.9h-4.4l-1.1.9z"
/>
<path
fill="#fff"
d="m27.8 25.6.9-5.6h-5.3v-3.9c0-1.6.6-2.8 3-2.8H29V8.2c-1.4-.2-3-.4-4.4-.4-4.6 0-7.8 2.8-7.8 7.8V20h-5v5.6h5v14.1c1.1.2 2.2.3 3.3.3 1.1 0 2.2-.1 3.3-.3V25.6h4.4z"
/>
</svg>
);
}

View file

@ -13,6 +13,7 @@ export { default as StopGeneratingIcon } from './StopGeneratingIcon';
export { default as RegenerateIcon } from './RegenerateIcon';
export { default as ContinueIcon } from './ContinueIcon';
export { default as GoogleIcon } from './GoogleIcon';
export { default as FacebookIcon } from './FacebookIcon';
export { default as OpenIDIcon } from './OpenIDIcon';
export { default as GithubIcon } from './GithubIcon';
export { default as DiscordIcon } from './DiscordIcon';