Skip to content

Commit

Permalink
✨ feat: FtOAuthRedirectPage (42 로그인)
Browse files Browse the repository at this point in the history
  • Loading branch information
yoopark committed Jul 9, 2023
1 parent af79881 commit aa24db2
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 19 deletions.
32 changes: 18 additions & 14 deletions app/src/components/elements/LoginButton/FtLoginButton.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import {
FT_OAUTH_ENDPOINT,
FT_OAUTH_RESPONSE_TYPE,
} from '@/constants/FT_OAUTH';
import ft_logo from '@assets/42-logo.svg';
import { Image } from '@components/common';
import { ROUTES } from '@routes/ROUTES';
import { useNavigate } from 'react-router-dom';
import { LoginButton } from './LoginButton';

export const FtLoginButton = () => {
const navigate = useNavigate();

const handleClick = () => {
// FIXME: 실제 로직으로 교체
localStorage.setItem('ftoauth', 'true');
navigate(ROUTES.HOME);
};
const params = new URLSearchParams();
params.append('client_id', import.meta.env.VITE_FT_OAUTH_CLIENT_ID);
params.append('redirect_uri', import.meta.env.VITE_FT_OAUTH_REDIRECT_URI);
params.append('response_type', FT_OAUTH_RESPONSE_TYPE);
const FT_OAUTH_URL = `${FT_OAUTH_ENDPOINT}?${params.toString()}`;

return (
<LoginButton
logo={<FtLogo />}
text="42 계정으로 로그인"
onClick={handleClick}
/>
<a href={FT_OAUTH_URL}>
<LoginButton
logo={<FtLogo />}
text="42 계정으로 로그인"
onClick={() => {
/* pass */
}}
/>
</a>
);
};

Expand Down
106 changes: 106 additions & 0 deletions app/src/pages/FtOAuthRedirectPage/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { gql } from '@/__generated__';
import { useMutation } from '@apollo/client';
import { userAtom } from '@atoms/userAtom';
import { Center, Loader } from '@components/common';
import { ROUTES } from '@routes/ROUTES';
import { setAccessToken } from '@utils/storage/accessToken';
import { getGoogleCredential } from '@utils/storage/googleCredential';
import { setRefreshToken } from '@utils/storage/refreshToken';
import { useSetAtom } from 'jotai';
import { useEffect, useState } from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';

const LOGIN_FT = gql(/* GraphQL */ `
mutation LoginFt($code: String!, $google: GoogleLoginInput) {
login(code: $code, google: $google) {
__typename
... on UnauthorizedType {
status
message
}
... on NotFoundType {
status
message
}
... on InternalServerErrorType {
status
message
}
... on SuccessType {
status
accessToken
refreshToken
userPreview {
id
login
imgUrl
displayname
}
}
}
}
`);

const FtOAuthRedirectPage = () => {
const [searchParams] = useSearchParams();
const code = searchParams.get('code');
const [login, { data, loading, error }] = useMutation(LOGIN_FT);
const navigate = useNavigate();

const [mounted, setMounted] = useState<boolean>(false);
const setUser = useSetAtom(userAtom);

useEffect(() => {
setMounted(true);
}, []);

useEffect(() => {
if (!code) {
return;
}
if (!mounted) {
return;
}
const credential = getGoogleCredential();
if (credential === null) {
login({ variables: { code } });
} else {
const clientId = import.meta.env.VITE_GAPI_CLIENT_ID;
login({
variables: {
code,
google: {
clientId,
credential,
},
},
});
}
}, [login, code, mounted]);

useEffect(() => {
if (loading || error || !data) {
console.log(loading, error, data);
return;
}
if (data.login.__typename !== 'SuccessType') {
console.log(data.login.status);
console.log(data.login.message);
navigate(ROUTES.ROOT);
} else {
const { accessToken, refreshToken, userPreview } = data.login;
const { id, login, imgUrl, displayname } = userPreview;
setUser({ id, login, imgUrl, displayname });
setAccessToken(accessToken);
setRefreshToken(refreshToken);
navigate(ROUTES.HOME);
}
}, [data, loading, error, navigate, setUser]);
return (
<Center>
<Loader />
</Center>
);
};

export default FtOAuthRedirectPage;
4 changes: 2 additions & 2 deletions app/src/routes/ROUTES.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
export const ROUTES = {
ROOT: '/',
HOME: '/home',
FTOAUTH: '/ftoauth',
FT_OAUTH: '/ftoauth',
FT_OAUTH_REDIRECT: '/auth/ft/redirect',
PROFILE_ROOT: '/profile',
PROFILE: '/profile/:username',
PROJECT_ROOT: '/project',
PROJECT_DETAIL: '/project/:projectName',
LEADERBOARD: '/leaderboard',
EVALLOG: '/evallog',
LOGOUT: '/logout',
SETTING: '/setting',
} as const;
9 changes: 6 additions & 3 deletions app/src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { LandingLayout } from '@layouts/LandingLayout';
import { MainLayout } from '@layouts/MainLayout';
import NotFoundPage from '@pages/Error/404';
import FtOAuthPage from '@pages/FtOAuthPage';
import LogoutPage from '@pages/LogoutPage';
import FtOAuthRedirectPage from '@pages/FtOAuthRedirectPage';
import { HomePageSkeleton } from '@pages/PageSkeletons/HomePageSkeleton';
import { ProfilePageSkeleton } from '@pages/PageSkeletons/ProfilePageSkeleton';
import SettingPage from '@pages/SettingPage';
Expand Down Expand Up @@ -36,7 +36,11 @@ export const AppRoutes = () => {
</Route>
</Route>
<Route element={<LandingLayout />}>
<Route path={ROUTES.FTOAUTH} element={<FtOAuthPage />} />
<Route path={ROUTES.FT_OAUTH} element={<FtOAuthPage />} />
<Route
path={ROUTES.FT_OAUTH_REDIRECT}
element={<FtOAuthRedirectPage />}
/>
</Route>
<Route element={<AuthGuard />}>
<Route element={<MainLayout />}>
Expand Down Expand Up @@ -112,7 +116,6 @@ export const AppRoutes = () => {
/>
<Route path={ROUTES.SETTING} element={<SettingPage />} />
</Route>
<Route path={ROUTES.LOGOUT} element={<LogoutPage />} />
</Route>
<Route element={<LandingLayout />}>
<Route path="*" element={<NotFoundPage />} />
Expand Down
3 changes: 3 additions & 0 deletions app/src/vite-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
interface ImportMetaEnv {
readonly VITE_BACKEND_GRAPHQL_ENDPOINT: string;
readonly VITE_GAPI_CLIENT_ID: string;
readonly VITE_FT_OAUTH_CLIENT_ID: string;
readonly VITE_FT_OAUTH_CLIENT_SECRET: string;
readonly VITE_FT_OAUTH_REDIRECT_URI: string;
}

interface ImportMeta {
Expand Down

0 comments on commit aa24db2

Please sign in to comment.