Skip to content
This repository has been archived by the owner on Aug 9, 2023. It is now read-only.

Commit

Permalink
Merge pull request #103 from isd-sgcu/dev
Browse files Browse the repository at this point in the history
feat: log in with google
  • Loading branch information
betich authored Aug 5, 2023
2 parents cf36097 + fb66ea9 commit 3e170ec
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 5 deletions.
22 changes: 21 additions & 1 deletion src/context/AuthContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface IAuthContext {
user?: IUser;
group?: IGroup;
login: () => void;
loginWithGoogle: () => void;
logout: () => void;
refreshContext: () => Promise<void>;
}
Expand Down Expand Up @@ -81,6 +82,11 @@ const AuthProvider = ({ children }: { children: ReactNode }) => {
router.push('/only-107');
}
break;
case '/login/choose':
if (isAuthenticated) {
router.push('/');
}
break;
case '/announce-baan':
case '/register':
case '/wait-baan-selection':
Expand All @@ -107,6 +113,10 @@ const AuthProvider = ({ children }: { children: ReactNode }) => {
window.location.href = `${process.env.NEXT_PUBLIC_SSO_BASE_URL}/login?service=${process.env.NEXT_PUBLIC_APP_BASE_URL}/login`;
}, []);

const loginWithGoogle = useCallback(() => {
window.location.href = `${process.env.NEXT_PUBLIC_API_BASE_URL}/auth/google`;
}, []);

const logout = useCallback(() => {
localStorage.clear();
window.location.href = '/login';
Expand All @@ -121,8 +131,18 @@ const AuthProvider = ({ children }: { children: ReactNode }) => {
login,
logout,
refreshContext,
loginWithGoogle,
}),
[isReady, isAuthenticated, user, group, login, logout, refreshContext]
[
isReady,
isAuthenticated,
user,
group,
login,
logout,
refreshContext,
loginWithGoogle,
]
);

return (
Expand Down
9 changes: 5 additions & 4 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Rocket from '@/public/images/rocket.svg';
import RocketSmoke from '@/public/images/rocket-smoke.svg';
import { useAuth } from '@/context/AuthContext';
import { shimmer, toBase64 } from '@/utils/shimmer';
import Link from 'next/link';

const Home = () => {
const { login } = useAuth();
Expand Down Expand Up @@ -35,12 +36,12 @@ const Home = () => {
<h2 className="z-0 mt-2 select-none text-5xl font-bold lg:text-8xl">
2023
</h2>
<button
<Link
href="/login/choose"
className="z-0 mt-6 select-none rounded-3xl bg-pink-400 px-6 py-3 text-2xl font-bold ring-8 ring-pink-400/30 transition-all duration-500 hover:scale-105 hover:ring-16 focus:outline-none lg:mt-16 lg:px-20 lg:py-4 lg:text-3xl lg:ring-16 lg:hover:ring-24"
onClick={login}
>
เข้าสู่ระบบด้วย Chula SSO
</button>
เข้าสู่ระบบ
</Link>
</main>
);
};
Expand Down
29 changes: 29 additions & 0 deletions src/pages/login/choose.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useAuth } from '@/context/AuthContext';

export default function LoginChoice() {
const { login, loginWithGoogle } = useAuth();

return (
<div className="flex min-h-screen flex-col items-center justify-center gap-10">
<h1 className="relative z-0 select-none text-5xl font-bold leading-none lg:text-7xl">
เข้าสู่ระบบ
</h1>

<div className="flex flex-col gap-4">
<button
className="z-0 select-none rounded-3xl bg-pink-400 px-6 py-3 text-2xl font-bold ring-8 ring-pink-400/30 transition-all duration-500 hover:scale-105 hover:ring-16 focus:outline-none lg:mt-16 lg:px-20 lg:py-4 lg:text-3xl lg:ring-16 lg:hover:ring-24"
onClick={login}
>
เข้าสู่ระบบด้วย Chula SSO
</button>

<button
className="z-0 select-none rounded-3xl bg-pink-400 px-6 py-3 text-2xl font-bold ring-8 ring-pink-400/30 transition-all duration-500 hover:scale-105 hover:ring-16 focus:outline-none lg:mt-16 lg:px-20 lg:py-4 lg:text-3xl lg:ring-16 lg:hover:ring-24"
onClick={loginWithGoogle}
>
เข้าสู่ระบบด้วย Google
</button>
</div>
</div>
);
}
File renamed without changes.
38 changes: 38 additions & 0 deletions src/pages/oauth/google.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { exchangeGoogleCodeForToken } from '@/utils/auth';
import { httpPost } from '@/utils/axios';
import { useRouter } from 'next/router';
import { useCallback, useEffect, useState } from 'react';

// example: https://freshmen2023.sgcu.in.th/oauth/google?code=4%2F0Adeu5BXJOzVuq9DUnfXhMaFmv8olktEtZato8IIX6_hvL_s1SWTZdv6Cj9LwJ00qg8duGw&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+openid&authuser=0&prompt=consent
export default function Google() {
const { query, replace, isReady } = useRouter();

const [message, setMessage] = useState('Loading...');

const handleLogin = useCallback(async (code: string) => {
try {
const token = await exchangeGoogleCodeForToken(code);
localStorage.setItem('token', JSON.stringify(token));
window.location.href = '/register';
} catch {
setMessage('Failed to login.');
}
}, []);

useEffect(() => {
if (isReady) {
if (query?.ticket) {
setMessage('Logging in...');
handleLogin(query.code as string);
} else {
replace('/');
}
}
}, [query, replace, handleLogin, isReady]);

return (
<div className="flex min-h-screen w-full flex-col items-center justify-center">
<p>{message}</p>
</div>
);
}
28 changes: 28 additions & 0 deletions src/utils/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,32 @@ const getAccessToken = async () => {
return accessToken;
};

// Google AUth

export const exchangeGoogleCodeForToken = async (
code: string
): Promise<ICredential | number | null> => {
let res: AxiosResponse;
try {
res = await authClient.post<ICredential>(
`/auth/google?code=${code}`,
{}
);
} catch (err) {
const error = err as AxiosError;
throw error;
// return error.response?.status ?? null;
}

const expiresOn = new Date();
expiresOn.setSeconds(expiresOn.getSeconds() + res.data.expires_in);
return {
accessToken: res.data.access_token,
refreshToken: res.data.refresh_token,
expiresOn,
};
};

// export const renewGoogleAccessToken = async (refreshToken: string) => {

export { exchangeTicketForToken, getAccessToken };

0 comments on commit 3e170ec

Please sign in to comment.