chore: google login implementation

pull/3813/head
Arik Chakma 2 years ago
parent df44dad61f
commit 0185bf179a
  1. 50
      src/components/Login/LoginComponent.tsx
  2. 6
      src/components/Login/account-nav.tsx
  3. 104
      src/components/Login/google-login.tsx
  4. 53
      src/pages/signup.astro

@ -1,5 +1,6 @@
import type { FunctionComponent } from 'preact'; import type { FunctionComponent } from 'preact';
import EmailLoginForm from './email-login-form'; import EmailLoginForm from './email-login-form';
import GoogleLoginButton from './google-login';
export default function LoginComponent() { export default function LoginComponent() {
return ( return (
@ -66,52 +67,3 @@ export const GithubLoginButton: FunctionComponent<{ className?: string }> = ({
</button> </button>
); );
}; };
export const GoogleLoginButton: FunctionComponent<{ className?: string }> = ({
className,
}) => {
return (
<button className="inline-flex h-10 w-full items-center justify-center rounded border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:opacity-60">
<GoogleLogo />
<span className="ml-2">Continue with Google</span>
</button>
);
};
function GoogleLogo() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height={18}
viewBox="0 0 186.69 190.5"
>
<g transform="translate(1184.583 765.171)">
<path
clipPath="none"
mask="none"
d="M-1089.333-687.239v36.888h51.262c-2.251 11.863-9.006 21.908-19.137 28.662l30.913 23.986c18.011-16.625 28.402-41.044 28.402-70.052 0-6.754-.606-13.249-1.732-19.483z"
fill="#4285f4"
/>
<path
clipPath="none"
mask="none"
d="M-1142.714-651.791l-6.972 5.337-24.679 19.223h0c15.673 31.086 47.796 52.561 85.03 52.561 25.717 0 47.278-8.486 63.038-23.033l-30.913-23.986c-8.486 5.715-19.31 9.179-32.125 9.179-24.765 0-45.806-16.712-53.34-39.226z"
fill="#34a853"
/>
<path
clipPath="none"
mask="none"
d="M-1174.365-712.61c-6.494 12.815-10.217 27.276-10.217 42.689s3.723 29.874 10.217 42.689c0 .086 31.693-24.592 31.693-24.592-1.905-5.715-3.031-11.776-3.031-18.098s1.126-12.383 3.031-18.098z"
fill="#fbbc05"
/>
<path
d="M-1089.333-727.244c14.028 0 26.497 4.849 36.455 14.201l27.276-27.276c-16.539-15.413-38.013-24.852-63.731-24.852-37.234 0-69.359 21.388-85.032 52.561l31.692 24.592c7.533-22.514 28.575-39.226 53.34-39.226z"
fill="#ea4335"
clipPath="none"
mask="none"
/>
</g>
</svg>
);
}

@ -12,7 +12,7 @@ export default function AccountNavigation() {
<div> <div>
{isLoading ? ( {isLoading ? (
<div className="flex h-10 w-32 items-center justify-center rounded-full bg-gradient-to-r from-blue-500 to-blue-700 py-2 px-4 text-sm text-white hover:from-blue-500 hover:to-blue-600"> <div className="flex h-10 w-32 items-center justify-center rounded-full bg-gradient-to-r from-blue-500 to-blue-700 py-2 px-4 text-sm text-white hover:from-blue-500 hover:to-blue-600">
<Spinner /> <Spinner className="text-white" />
</div> </div>
) : ( ) : (
<> <>
@ -32,10 +32,10 @@ export default function AccountNavigation() {
); );
} }
function Spinner() { export function Spinner({className}: {className?: string}) {
return ( return (
<svg <svg
className="h-5 w-5 animate-spin text-white" className={`h-5 w-5 animate-spin ${className}`}
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
fill="none" fill="none"
viewBox="0 0 24 24" viewBox="0 0 24 24"

@ -0,0 +1,104 @@
import Cookies from 'js-cookie';
import { useEffect, useState } from 'preact/hooks';
import { TOKEN_COOKIE_NAME } from '../../lib/utils';
import { Spinner } from './account-nav';
export default function GoogleLoginButton() {
const [isLoading, setIsLoading] = useState<boolean>(false);
const handleRedirect = () => {
setIsLoading(true);
fetch('http://localhost:8080/v1-google-login', {
credentials: 'include',
})
.then((res) => res.json())
.then((data) => {
setIsLoading(false);
window.location.href = data.loginUrl;
});
};
useEffect(() => {
// Get all query params and send them to v1-google-callback
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
const prompt = urlParams.get('prompt');
if (code && state && prompt) {
setIsLoading(true);
fetch(
`http://localhost:8080/v1-google-callback${window.location.search}`,
{
method: 'GET',
credentials: 'include',
}
)
.then((res) => res.json())
.then((data) => {
if (data.token) {
Cookies.set(TOKEN_COOKIE_NAME, data.token);
setIsLoading(false);
window.location.href = '/';
}
})
.catch((err) => {
console.log(err);
});
}
}, []);
return (
<button
className="mt-2 inline-flex h-10 w-full items-center justify-center rounded border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:opacity-60"
onClick={handleRedirect}
>
{isLoading ? (
<Spinner className="text-black" />
) : (
<>
<GoogleLogo />
<span className="ml-2">Continue with Google</span>
</>
)}
</button>
);
}
function GoogleLogo() {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height={18}
viewBox="0 0 186.69 190.5"
>
<g transform="translate(1184.583 765.171)">
<path
clipPath="none"
mask="none"
d="M-1089.333-687.239v36.888h51.262c-2.251 11.863-9.006 21.908-19.137 28.662l30.913 23.986c18.011-16.625 28.402-41.044 28.402-70.052 0-6.754-.606-13.249-1.732-19.483z"
fill="#4285f4"
/>
<path
clipPath="none"
mask="none"
d="M-1142.714-651.791l-6.972 5.337-24.679 19.223h0c15.673 31.086 47.796 52.561 85.03 52.561 25.717 0 47.278-8.486 63.038-23.033l-30.913-23.986c-8.486 5.715-19.31 9.179-32.125 9.179-24.765 0-45.806-16.712-53.34-39.226z"
fill="#34a853"
/>
<path
clipPath="none"
mask="none"
d="M-1174.365-712.61c-6.494 12.815-10.217 27.276-10.217 42.689s3.723 29.874 10.217 42.689c0 .086 31.693-24.592 31.693-24.592-1.905-5.715-3.031-11.776-3.031-18.098s1.126-12.383 3.031-18.098z"
fill="#fbbc05"
/>
<path
d="M-1089.333-727.244c14.028 0 26.497 4.849 36.455 14.201l27.276-27.276c-16.539-15.413-38.013-24.852-63.731-24.852-37.234 0-69.359 21.388-85.032 52.561l31.692 24.592c7.533-22.514 28.575-39.226 53.34-39.226z"
fill="#ea4335"
clipPath="none"
mask="none"
/>
</g>
</svg>
);
}

@ -1,12 +1,9 @@
--- ---
import CaptchaFields from '../components/Captcha/CaptchaFields.astro'; import CaptchaFields from '../components/Captcha/CaptchaFields.astro';
import CaptchaScripts from '../components/Captcha/CaptchaScripts.astro'; import CaptchaScripts from '../components/Captcha/CaptchaScripts.astro';
import { import { Divider, GithubLoginButton } from '../components/Login/LoginComponent';
Divider,
GithubLoginButton,
GoogleLoginButton,
} from '../components/Login/LoginComponent';
import EmailLoginForm from '../components/Login/email-login-form'; import EmailLoginForm from '../components/Login/email-login-form';
import GoogleLoginButton from '../components/Login/google-login';
import BaseLayout from '../layouts/BaseLayout.astro'; import BaseLayout from '../layouts/BaseLayout.astro';
--- ---
@ -32,12 +29,8 @@ import BaseLayout from '../layouts/BaseLayout.astro';
</p> </p>
</div> </div>
<div class='w-full space-y-2'>
<button login-google>login with google</button>
<GithubLoginButton /> <GithubLoginButton />
<GoogleLoginButton /> <GoogleLoginButton client:load />
</div>
<Divider /> <Divider />
@ -49,40 +42,10 @@ import BaseLayout from '../layouts/BaseLayout.astro';
</BaseLayout> </BaseLayout>
<script> <script>
document import Cookies from 'js-cookie';
.querySelector('button[login-google]') import { TOKEN_COOKIE_NAME } from '../lib/utils';
?.addEventListener('click', () => { const token = Cookies.get(TOKEN_COOKIE_NAME);
fetch('http://localhost:8080/v1-google-login', { if (token) {
credentials: 'include', window.location.href = '/';
})
.then((res) => res.json())
.then((data) => {
window.location.href = data.loginUrl;
});
});
window.addEventListener('load', () => {
// Get all query params and send them to v1-google-callback
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
const prompt = urlParams.get('prompt');
if (code && state && prompt) {
fetch(
`http://localhost:8080/v1-google-callback${window.location.search}`,
{
method: 'get',
credentials: 'include',
}
)
.then((res) => res.json())
.then((data) => {
console.log(data);
})
.catch((err) => {
console.log(err);
});
} }
});
</script> </script>

Loading…
Cancel
Save