diff --git a/shared/widgets/signin/actions/submitProviderCallback.ts b/features/authCallback/actions/submitProviderCallback.ts similarity index 100% rename from shared/widgets/signin/actions/submitProviderCallback.ts rename to features/authCallback/actions/submitProviderCallback.ts diff --git a/features/authCallback/index.tsx b/features/authCallback/index.tsx index 012b0b7..b934d09 100644 --- a/features/authCallback/index.tsx +++ b/features/authCallback/index.tsx @@ -1,25 +1,33 @@ "use client"; import { Spinner } from "@/shared/libs/shadcn/ui/spinner"; -import { submitProviderCallback } from "@/shared/widgets/signin/actions/submitProviderCallback"; +import { submitProviderCallback } from "@/features/authCallback/actions/submitProviderCallback"; import { useParams, useRouter, useSearchParams } from "next/navigation"; import { useEffect, useState } from "react"; const AuthCallbackIndex = () => { const { name } = useParams(); const queries = useSearchParams().toString(); - const router = useRouter(); const [textDescription, setTextDescription] = useState( "We are processing your authentication." ); + const finishOAuthFlow = (type: string) => { + setTimeout(() => { + if (!window.opener) window.location.href = "/"; + window.opener.postMessage({ type: type }, window.location.origin); + window.close(); + }, 1000); + }; + useEffect(() => { (async () => { const response = await submitProviderCallback(name as string, queries); if (response.success) { setTextDescription("Authentication successful! Redirecting..."); - router.push("/"); + finishOAuthFlow("oauth-success"); } else { setTextDescription("Authentication failed. Please try again."); + finishOAuthFlow("oauth-failed"); } })(); }, []); diff --git a/shared/widgets/signin/components/SignInCard.tsx b/shared/widgets/signin/components/SignInCard.tsx index d2a236c..c631832 100644 --- a/shared/widgets/signin/components/SignInCard.tsx +++ b/shared/widgets/signin/components/SignInCard.tsx @@ -10,7 +10,7 @@ import { import { Input } from "@/shared/libs/shadcn/ui/input"; import { Label } from "@/shared/libs/shadcn/ui/label"; import { Separator } from "@/shared/libs/shadcn/ui/separator"; -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { getAllThirdPartyAuth, GetALlThirdPartyAuthCallback, @@ -18,14 +18,13 @@ import { import { Icon } from "@iconify/react"; import { Spinner } from "@/shared/libs/shadcn/ui/spinner"; import { getOauthEndpoint } from "../actions/getOauthEndpoint"; -import { useRouter } from "next/navigation"; const SignInCard = () => { - const router = useRouter(); const [isLoading, setIsLoading] = useState(false); const [oAuthProviders, setOAuthProviders] = useState(null); + // Fetch available third-party auth providers on component mount useEffect(() => { (async () => { const res = await getAllThirdPartyAuth(); @@ -33,6 +32,7 @@ const SignInCard = () => { })(); }, []); + // Open OAuth endpoint in a new popup window const getOauthEndpointUrl = async ( providerReqEndpoint: string, providerName: string @@ -41,9 +41,25 @@ const SignInCard = () => { endpointUrl: providerReqEndpoint, providerName: providerName, }); - router.push(res.data?.endpointUrl || "/"); + + setIsLoading(true); + window.open(res.data?.endpointUrl, "oauthPopup", "width=500,height=600"); }; + // Handle the feedback from popup window for OAuth + const handleMessage = useCallback((event: MessageEvent) => { + if (event.origin !== window.location.origin) return; + if (event.data.type === "oauth-success") window.location.reload(); + if (event.data.type === "oauth-failed") setIsLoading(false); + }, []); + + useEffect(() => { + window.addEventListener("message", handleMessage); + return () => { + window.removeEventListener("message", handleMessage); + }; + }, [handleMessage]); + return (