import EmbyLogo from '@app/assets/services/emby-icon-only.svg'; import JellyfinLogo from '@app/assets/services/jellyfin-icon.svg'; import PlexLogo from '@app/assets/services/plex.svg'; import Button from '@app/components/Common/Button'; import ImageFader from '@app/components/Common/ImageFader'; import PageTitle from '@app/components/Common/PageTitle'; import LanguagePicker from '@app/components/Layout/LanguagePicker'; import JellyfinLogin from '@app/components/Login/JellyfinLogin'; import LocalLogin from '@app/components/Login/LocalLogin'; import PlexLoginButton from '@app/components/Login/PlexLoginButton'; import useSettings from '@app/hooks/useSettings'; import { useUser } from '@app/hooks/useUser'; import defineMessages from '@app/utils/defineMessages'; import { Transition } from '@headlessui/react'; import { XCircleIcon } from '@heroicons/react/24/solid'; import { MediaServerType } from '@server/constants/server'; import axios from 'axios'; import { useRouter } from 'next/dist/client/router'; import Image from 'next/image'; import { useEffect, useRef, useState } from 'react'; import { useIntl } from 'react-intl'; import { CSSTransition, SwitchTransition } from 'react-transition-group'; import useSWR from 'swr'; const messages = defineMessages('components.Login', { signin: 'Sign In', signinheader: 'Sign in to continue', signinwithplex: 'Use your Plex account', signinwithjellyfin: 'Use your {mediaServerName} account', signinwithoverseerr: 'Use your {applicationTitle} account', orsigninwith: 'Or sign in with', }); const Login = () => { const intl = useIntl(); const router = useRouter(); const settings = useSettings(); const { user, revalidate } = useUser(); const [error, setError] = useState(''); const [isProcessing, setProcessing] = useState(false); const [authToken, setAuthToken] = useState(undefined); const [mediaServerLogin, setMediaServerLogin] = useState( settings.currentSettings.mediaServerLogin ); // Effect that is triggered when the `authToken` comes back from the Plex OAuth // We take the token and attempt to sign in. If we get a success message, we will // ask swr to revalidate the user which _should_ come back with a valid user. useEffect(() => { const login = async () => { setProcessing(true); try { const response = await axios.post('/api/v1/auth/plex', { authToken }); if (response.data?.id) { revalidate(); } } catch (e) { setError(e.response?.data?.message); setAuthToken(undefined); setProcessing(false); } }; if (authToken) { login(); } }, [authToken, revalidate]); // Effect that is triggered whenever `useUser`'s user changes. If we get a new // valid user, we redirect the user to the home page as the login was successful. useEffect(() => { if (user) { router.push('/'); } }, [user, router]); const { data: backdrops } = useSWR('/api/v1/backdrops', { refreshInterval: 0, refreshWhenHidden: false, revalidateOnFocus: false, }); const mediaServerName = settings.currentSettings.mediaServerType === MediaServerType.PLEX ? 'Plex' : settings.currentSettings.mediaServerType === MediaServerType.JELLYFIN ? 'Jellyfin' : settings.currentSettings.mediaServerType === MediaServerType.EMBY ? 'Emby' : undefined; const MediaServerLogo = settings.currentSettings.mediaServerType === MediaServerType.PLEX ? PlexLogo : settings.currentSettings.mediaServerType === MediaServerType.JELLYFIN ? JellyfinLogo : settings.currentSettings.mediaServerType === MediaServerType.EMBY ? EmbyLogo : undefined; const isJellyfin = settings.currentSettings.mediaServerType === MediaServerType.JELLYFIN || settings.currentSettings.mediaServerType === MediaServerType.EMBY; const mediaServerLoginRef = useRef(null); const localLoginRef = useRef(null); const loginRef = mediaServerLogin ? mediaServerLoginRef : localLoginRef; const loginFormVisible = (isJellyfin && settings.currentSettings.mediaServerLogin) || settings.currentSettings.localLogin; const additionalLoginOptions = [ settings.currentSettings.mediaServerLogin && (settings.currentSettings.mediaServerType === MediaServerType.PLEX ? ( setAuthToken(authToken)} large={!isJellyfin && !settings.currentSettings.localLogin} /> ) : ( settings.currentSettings.localLogin && (mediaServerLogin ? ( ) : ( )) )), ].filter((o): o is JSX.Element => !!o); return (
`https://image.tmdb.org/t/p/original${backdrop}` ) ?? [] } />
Logo
<>

{error}

{ loginRef.current?.addEventListener( 'transitionend', done, false ); }} onEntered={() => { document .querySelector('#email, #username') ?.focus(); }} classNames={{ appear: 'opacity-0', appearActive: 'transition-opacity duration-500 opacity-100', enter: 'opacity-0', enterActive: 'transition-opacity duration-500 opacity-100', exitActive: 'transition-opacity duration-0 opacity-0', }} >
{isJellyfin && (mediaServerLogin || !settings.currentSettings.localLogin) ? ( ) : ( settings.currentSettings.localLogin && ( ) )}
{additionalLoginOptions.length > 0 && (loginFormVisible ? (
{intl.formatMessage(messages.orsigninwith)}
) : (

{intl.formatMessage(messages.signinheader)}

))}
{additionalLoginOptions}
); }; export default Login;