From 7dc2e56fee1afc1078774cc702c0f1fee9bae938 Mon Sep 17 00:00:00 2001 From: Elias Schneider Date: Sat, 14 Sep 2024 18:12:41 +0200 Subject: [PATCH] feat: auto redirect to oauth provider --- frontend/src/components/auth/SignInForm.tsx | 48 +++++++++++++++------ frontend/src/i18n/translations/en-US.ts | 1 + 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/frontend/src/components/auth/SignInForm.tsx b/frontend/src/components/auth/SignInForm.tsx index de6436d6..1dc16001 100644 --- a/frontend/src/components/auth/SignInForm.tsx +++ b/frontend/src/components/auth/SignInForm.tsx @@ -4,6 +4,7 @@ import { Container, createStyles, Group, + Loader, Paper, PasswordInput, Stack, @@ -15,7 +16,7 @@ import { useForm, yupResolver } from "@mantine/form"; import { showNotification } from "@mantine/notifications"; import Link from "next/link"; import { useRouter } from "next/router"; -import React from "react"; +import { useEffect, useState } from "react"; import { TbInfoCircle } from "react-icons/tb"; import { FormattedMessage } from "react-intl"; import * as yup from "yup"; @@ -24,8 +25,8 @@ import useUser from "../../hooks/user.hook"; import useTranslate from "../../hooks/useTranslate.hook"; import authService from "../../services/auth.service"; import { getOAuthIcon, getOAuthUrl } from "../../utils/oauth.util"; -import toast from "../../utils/toast.util"; import { safeRedirectPath } from "../../utils/router.util"; +import toast from "../../utils/toast.util"; const useStyles = createStyles((theme) => ({ signInWith: { @@ -74,7 +75,9 @@ const SignInForm = ({ redirectPath }: { redirectPath: string }) => { const { refreshUser } = useUser(); const { classes } = useStyles(); - const [oauth, setOAuth] = React.useState([]); + const [oauthProviders, setOauthProviders] = useState(null); + const [isRedirectingToOauthProvider, setIsRedirectingToOauthProvider] = + useState(false); const validationSchema = yup.object().shape({ emailOrUsername: yup.string().required(t("common.error.field-required")), @@ -118,15 +121,36 @@ const SignInForm = ({ redirectPath }: { redirectPath: string }) => { .catch(toast.axiosError); }; - const getAvailableOAuth = async () => { - const oauth = await authService.getAvailableOAuth(); - setOAuth(oauth.data); - }; - - React.useEffect(() => { - getAvailableOAuth().catch(toast.axiosError); + useEffect(() => { + authService + .getAvailableOAuth() + .then((providers) => { + setOauthProviders(providers.data); + if ( + providers.data.length === 1 && + config.get("oauth.disablePassword") + ) { + setIsRedirectingToOauthProvider(true); + router.push( + getOAuthUrl(config.get("general.appUrl"), providers.data[0]), + ); + } + }) + .catch(toast.axiosError); }, []); + if (!oauthProviders) return null; + + if (isRedirectingToOauthProvider) + return ( + + + + + + + ); + return ( @@ -170,7 +194,7 @@ const SignInForm = ({ redirectPath }: { redirectPath: string }) => { </Button> </form> )} - {oauth.length > 0 && ( + {oauthProviders.length > 0 && ( <Stack mt={config.get("oauth.disablePassword") ? undefined : "xl"}> {config.get("oauth.disablePassword") ? ( <Group align="center" className={classes.signInWith}> @@ -182,7 +206,7 @@ const SignInForm = ({ redirectPath }: { redirectPath: string }) => { </Group> )} <Group position="center"> - {oauth.map((provider) => ( + {oauthProviders.map((provider) => ( <Button key={provider} component="a" diff --git a/frontend/src/i18n/translations/en-US.ts b/frontend/src/i18n/translations/en-US.ts index dd700482..a6a75074 100644 --- a/frontend/src/i18n/translations/en-US.ts +++ b/frontend/src/i18n/translations/en-US.ts @@ -631,6 +631,7 @@ export default { "common.text.link": "Link", "common.text.navigate-to-link": "Go to the link", "common.text.or": "or", + "common.text.redirecting": "Redirecting...", "common.button.go-back": "Go back", "common.button.go-home": "Go home", "common.notify.copied": "Your link was copied to the clipboard",