From d1cadad18375382c4425b2b415537970d683c1da Mon Sep 17 00:00:00 2001 From: mehrzadghdev Date: Mon, 25 Aug 2025 23:42:29 +0330 Subject: [PATCH] chore: auth factory --- .../AuthenticationSteps.tsx | 74 ++++++++++++++----- .../GoogleAuthentication.tsx | 7 +- .../AuthenticationSteps/LoginRegiserForm.tsx | 6 +- .../authentication/types/authTypes.ts | 7 ++ 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/src/features/authentication/components/AuthenticationSteps/AuthenticationSteps.tsx b/src/features/authentication/components/AuthenticationSteps/AuthenticationSteps.tsx index 841c0c3..9b57c60 100644 --- a/src/features/authentication/components/AuthenticationSteps/AuthenticationSteps.tsx +++ b/src/features/authentication/components/AuthenticationSteps/AuthenticationSteps.tsx @@ -1,6 +1,12 @@ -import { useState, type JSX } from 'react'; +import { useMemo, useState, type JSX } from 'react'; import { LoginRegisterForm } from './LoginRegiserForm'; -import type { AuthMode, AuthStep, AuthType } from '../../types/authTypes'; +import type { + AuthFactory, + AuthMode, + AuthRedirector, + AuthStep, + AuthType, +} from '../../types/authTypes'; import { OtpVerifyForm } from './OtpVerifyForm'; import { isNumeric } from '@/utils/regexes/isNumeric'; import { CompleteSignUp } from './CompleteSignUp'; @@ -14,12 +20,6 @@ import { REFRESH_TOKEN_KEY } from '@/providers/AuthProvider'; export const AuthenticationSteps = (): JSX.Element => { const navigate = useNavigate(); const [searchParams] = useSearchParams(); - const authReturnUrl: string | null = searchParams.get('returnUrl'); - const authReturnUrlWithRefreshToken = - authReturnUrl + `?token=${sessionStorage.getItem(REFRESH_TOKEN_KEY)}`; - authReturnUrl + `?token=${sessionStorage.getItem(REFRESH_TOKEN_KEY)}`; - const authReturnUrlOrDefault: string = - authReturnUrl ?? import.meta.env.VITE_DEFUALT_AUTH_RETURN_URL; const [authMode, setAuthMode] = useState('register'); const [authType, setAuthType] = useState('phone'); const [currentStep, setCurrentStep] = useState('emailOrPhone'); @@ -30,6 +30,33 @@ export const AuthenticationSteps = (): JSX.Element => { const [addedPhoneNumberValue, setAddedPhoneNumberValue] = useState(''); + const authFactory: AuthFactory = useMemo(() => { + const redirectUrl = searchParams.get('redirect_url'); + const clientId = searchParams.get('client_id'); + + if (!clientId) { + const defaultFactory: AuthFactory = { + clientId: import.meta.env.VITE_IDENTITY_CLIENT_ID, + redirectUrl: 'accounts.', + accountsApplication + setLocalToken: true, + }; + + return defaultFactory; + } + + const resFactory: AuthFactory = { + clientId: clientId, + redirectUrl: redirectUrl as string, + setLocalToken: true, + getFullRedirectUrl: function (token: string) { + return this.redirectUrl + '?token=' + token; + }, + }; + + return resFactory; + }, [searchParams]); + const handleLoginRegister = (value: string, userStatus: UserStatus) => { setAuthType(isNumeric(value) ? 'phone' : 'email'); @@ -53,40 +80,49 @@ export const AuthenticationSteps = (): JSX.Element => { } }; - const handleUserLoggedIn = (loginResult: LoginResult) => { + const handleUserLoggedIn = ( + loginResult: LoginResult, + refreshToken: string, + ) => { if (loginResult.registeredWithOutPhoneNumber) { setCurrentStep('addPhoneNumber'); return; } if (!loginResult.completedUserInformation) { - if (authReturnUrl) { - navigate(`/signup?returnUrl=${authReturnUrlWithRefreshToken}`); + if (authFactory.redirectUrl) { + navigate( + `/signup?returnUrl=${authFactory.getFullRedirectUrl(refreshToken)}`, + ); } else { navigate(`/signup`); } return; } - redirectToReturnUrl(); + redirectToReturnUrl(refreshToken); }; - const handlePhoneNumberVerified = () => { - if (authReturnUrl) { - navigate(`/signup?returnUrl=${authReturnUrlWithRefreshToken}`); + const handlePhoneNumberVerified = (refreshToken: string) => { + if (authFactory.redirectUrl) { + navigate( + `/signup?returnUrl=${authFactory.getFullRedirectUrl(refreshToken)}`, + ); } else { navigate(`/signup`); } }; - const redirectToReturnUrl = () => { - if (!authReturnUrl) { + const redirectToReturnUrl = (refreshToken: string) => { + if (!authFactory.redirectUrl) { navigate(import.meta.env.VITE_DEFUALT_AUTH_RETURN_URL); } else { if (authMode === 'register') { - navigate(`/account-created?returnUrl=${authReturnUrlWithRefreshToken}`); + navigate( + `/account-created?returnUrl=${authFactory.getFullRedirectUrl(refreshToken)}`, + ); } else { - location.href = authReturnUrlWithRefreshToken; + location.href = authFactory.getFullRedirectUrl(refreshToken); } } }; diff --git a/src/features/authentication/components/AuthenticationSteps/GoogleAuthentication.tsx b/src/features/authentication/components/AuthenticationSteps/GoogleAuthentication.tsx index fff5e7f..eab83b6 100644 --- a/src/features/authentication/components/AuthenticationSteps/GoogleAuthentication.tsx +++ b/src/features/authentication/components/AuthenticationSteps/GoogleAuthentication.tsx @@ -12,16 +12,17 @@ import { Icon, useToast } from '@rkheftan/harmony-ui'; import { useApi } from '@/hooks/useApi'; import { generateTokenWithGoogle } from '../../api/identityAPI'; import { useAuth } from '@/hooks/useAuth'; +import type { AuthFactory } from '../../types/authTypes'; export interface GoogleAuthenticationProps { disabled: boolean; - authReturnUrl: string; + authFactory: AuthFactory; onGoogleAuthenticated: (loginResult: LoginResult) => void; } export const GoogleAuthentication = ({ disabled, - authReturnUrl, + authFactory, onGoogleAuthenticated, }: GoogleAuthenticationProps) => { const { t } = useTranslation('authentication'); @@ -47,7 +48,7 @@ export const GoogleAuthentication = ({ callback: async (resp: GoogleCodeClientResponse) => { const apiRequest: LoginOrSignUpWithGoogleRequest = { idToken: resp.id_token, - returnUrl: authReturnUrl, + returnUrl: authFactory.redirectUrl, }; const res = await loginWithGoogleCall(apiRequest); diff --git a/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx b/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx index 193a5ff..53db6d9 100644 --- a/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx +++ b/src/features/authentication/components/AuthenticationSteps/LoginRegiserForm.tsx @@ -2,7 +2,7 @@ import { Button, Stack, TextField, Typography } from '@mui/material'; import { useRef, useState, type Dispatch } from 'react'; import { useTranslation } from 'react-i18next'; import { isNumeric } from '@/utils/regexes/isNumeric'; -import type { AuthType } from '../../types/authTypes'; +import type { AuthFactory, AuthType } from '../../types/authTypes'; import { isEmail } from '@/utils/regexes/isEmail'; import { AuthenticationCard } from '../AuthenticationCard'; import { CountryCodeSelector } from '../CountryCodeSelector'; @@ -22,8 +22,8 @@ export interface LoginRegisterFormProps { authType: AuthType; setAuthType: Dispatch; onLoginRegisterSubmit: (value: string, userStatus: UserStatus) => void; - authReturnUrl: string; onGoogleAuthenticated: (loginResult: LoginResult) => void; + authFactory: AuthFactory; } export function LoginRegisterForm({ @@ -34,8 +34,8 @@ export function LoginRegisterForm({ authType, setAuthType, onLoginRegisterSubmit, - authReturnUrl, onGoogleAuthenticated, + authFactory, }: LoginRegisterFormProps) { const { t } = useTranslation('authentication'); const textFieldRef = useRef(null); diff --git a/src/features/authentication/types/authTypes.ts b/src/features/authentication/types/authTypes.ts index 91e45f5..d2ccc48 100644 --- a/src/features/authentication/types/authTypes.ts +++ b/src/features/authentication/types/authTypes.ts @@ -8,3 +8,10 @@ export type AuthStep = | 'enterPassword' | 'addPhoneNumber' | 'addedPhoneNumberVerify'; + +export interface AuthFactory { + clientId: string; + redirectUrl: string | null; + accountsApplication: boolean; + getFullRedirectUrl: (token: string) => string; +}