211 lines
6.7 KiB
TypeScript
211 lines
6.7 KiB
TypeScript
import { useMemo, useState, type JSX } from 'react';
|
|
import { LoginRegisterForm } from './LoginRegiserForm';
|
|
import type {
|
|
AuthFactory,
|
|
AuthMode,
|
|
AuthStep,
|
|
AuthType,
|
|
} from '../../types/authTypes';
|
|
import { OtpVerifyForm } from './OtpVerifyForm';
|
|
import { isNumeric } from '@/utils/regexes/isNumeric';
|
|
import { CompleteSignUp } from './CompleteSignUp';
|
|
import { EnterPasswordForm } from './EnterPasswordForm';
|
|
import { UserStatus, type LoginResult } from '../../types/userTypes';
|
|
import type { CountryCode } from '@/types/commonTypes';
|
|
import { VerifyPhoneNumber } from './VerifyPhoneNumber';
|
|
import { useNavigate, useSearchParams } from 'react-router-dom';
|
|
import type { GenerateTokenResponse } from '../../api/identityAPI';
|
|
import { useAuth } from '@/hooks/useAuth';
|
|
|
|
export const AuthenticationSteps = (): JSX.Element => {
|
|
const navigate = useNavigate();
|
|
const [searchParams] = useSearchParams();
|
|
const [authMode, setAuthMode] = useState<AuthMode>('register');
|
|
const [authType, setAuthType] = useState<AuthType>('phone');
|
|
const [currentStep, setCurrentStep] = useState<AuthStep>('emailOrPhone');
|
|
const [loginRegisterValue, setLoginRegisterValue] = useState<string>('');
|
|
const [countryCode, setCountryCode] = useState<CountryCode>('+98');
|
|
const [addPhoneCountryCode, setAddPhoneCountryCode] =
|
|
useState<CountryCode>('+98');
|
|
const [addedPhoneNumberValue, setAddedPhoneNumberValue] =
|
|
useState<string>('');
|
|
const [memoryTokenRes, setMemoryTokenRes] = useState<GenerateTokenResponse>();
|
|
const [hasPassword, setHasPassword] = useState(false);
|
|
const { login } = useAuth();
|
|
|
|
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: import.meta.env.VITE_APP_URL,
|
|
isCurrentApplication: function () {
|
|
return this.clientId === import.meta.env.VITE_IDENTITY_CLIENT_ID;
|
|
},
|
|
getFullRedirectUrl: function (token: string) {
|
|
return this.redirectUrl + '?token=' + token;
|
|
},
|
|
};
|
|
|
|
return defaultFactory;
|
|
}
|
|
|
|
const resFactory: AuthFactory = {
|
|
clientId: clientId,
|
|
redirectUrl: redirectUrl as string,
|
|
isCurrentApplication: function () {
|
|
return this.clientId === import.meta.env.VITE_IDENTITY_CLIENT_ID;
|
|
},
|
|
getFullRedirectUrl: function (token: string) {
|
|
return this.redirectUrl + '?token=' + token;
|
|
},
|
|
};
|
|
|
|
return resFactory;
|
|
}, [searchParams]);
|
|
|
|
const handleLoginRegister = (value: string, userStatus: UserStatus) => {
|
|
setAuthType(isNumeric(value) ? 'phone' : 'email');
|
|
|
|
switch (userStatus) {
|
|
case UserStatus.NotRegistered:
|
|
setAuthMode('register');
|
|
setCurrentStep('verify');
|
|
break;
|
|
|
|
case UserStatus.RegisteredWithoutPassword:
|
|
setAuthMode('login');
|
|
setCurrentStep('verify');
|
|
|
|
break;
|
|
|
|
case UserStatus.RegisteredWithPassword:
|
|
setAuthMode('login');
|
|
setCurrentStep('enterPassword');
|
|
setHasPassword(true);
|
|
|
|
break;
|
|
}
|
|
};
|
|
|
|
const handleUserLoggedIn = (
|
|
loginResult: LoginResult,
|
|
tokenResponse: GenerateTokenResponse,
|
|
) => {
|
|
setMemoryTokenRes(tokenResponse);
|
|
// TODO: For now both application scopes can have their tokens
|
|
// later we need to discuss this base on business plan and change it
|
|
// if (authFactory.isCurrentApplication()) {}
|
|
login(tokenResponse);
|
|
|
|
if (loginResult.registeredWithOutPhoneNumber) {
|
|
setCurrentStep('addPhoneNumber');
|
|
return;
|
|
}
|
|
|
|
if (!loginResult.completedUserInformation) {
|
|
if (!authFactory.isCurrentApplication()) {
|
|
navigate(
|
|
`/signup?returnUrl=${authFactory.getFullRedirectUrl(tokenResponse.refresh_token)}`,
|
|
);
|
|
} else {
|
|
navigate(`/signup`);
|
|
}
|
|
return;
|
|
}
|
|
|
|
redirectToReturnUrl(tokenResponse.refresh_token);
|
|
};
|
|
|
|
const handlePhoneNumberVerified = () => {
|
|
if (!authFactory.isCurrentApplication()) {
|
|
navigate(
|
|
`/signup?returnUrl=${authFactory.getFullRedirectUrl(memoryTokenRes?.refresh_token as string)}`,
|
|
);
|
|
} else {
|
|
navigate(`/signup`);
|
|
}
|
|
};
|
|
|
|
const redirectToReturnUrl = (refreshToken: string) => {
|
|
if (authFactory.isCurrentApplication()) {
|
|
navigate(import.meta.env.VITE_DEFUALT_AUTH_RETURN_URL);
|
|
} else {
|
|
if (authMode === 'register') {
|
|
navigate(
|
|
`/account-created?returnUrl=${authFactory.getFullRedirectUrl(refreshToken)}`,
|
|
);
|
|
} else {
|
|
location.href = authFactory.getFullRedirectUrl(refreshToken);
|
|
}
|
|
}
|
|
};
|
|
|
|
return (
|
|
<>
|
|
{currentStep === 'emailOrPhone' && (
|
|
<LoginRegisterForm
|
|
authFactory={authFactory}
|
|
onGoogleAuthenticated={handleUserLoggedIn}
|
|
countryCode={countryCode}
|
|
setCountryCode={setCountryCode}
|
|
loginRegisterValue={loginRegisterValue}
|
|
setLoginRegisterValue={setLoginRegisterValue}
|
|
authType={authType}
|
|
setAuthType={setAuthType}
|
|
onLoginRegisterSubmit={handleLoginRegister}
|
|
/>
|
|
)}
|
|
|
|
{currentStep === 'verify' && (
|
|
<OtpVerifyForm
|
|
authFactory={authFactory}
|
|
countryCode={countryCode}
|
|
onOTPVerified={handleUserLoggedIn}
|
|
onEditValue={() => setCurrentStep('emailOrPhone')}
|
|
authMode={authMode}
|
|
authType={authType}
|
|
value={loginRegisterValue}
|
|
hasPassword={hasPassword}
|
|
onLoginWithPassword={() => setCurrentStep('enterPassword')}
|
|
/>
|
|
)}
|
|
|
|
{currentStep === 'enterPassword' && (
|
|
<EnterPasswordForm
|
|
authFactory={authFactory}
|
|
loginRegisterValue={loginRegisterValue}
|
|
countryCode={countryCode}
|
|
authType={authType}
|
|
onLoggedIn={handleUserLoggedIn}
|
|
onEditValue={() => setCurrentStep('emailOrPhone')}
|
|
onLoginWithOTP={() => setCurrentStep('verify')}
|
|
emailOrPhone={loginRegisterValue}
|
|
/>
|
|
)}
|
|
|
|
{currentStep === 'addPhoneNumber' && (
|
|
<CompleteSignUp
|
|
countryCode={addPhoneCountryCode}
|
|
setCountryCode={setAddPhoneCountryCode}
|
|
value={addedPhoneNumberValue}
|
|
setValue={setAddedPhoneNumberValue}
|
|
email={loginRegisterValue}
|
|
onCompleteSignUp={() => setCurrentStep('addedPhoneNumberVerify')}
|
|
/>
|
|
)}
|
|
|
|
{currentStep === 'addedPhoneNumberVerify' && (
|
|
<VerifyPhoneNumber
|
|
countryCode={countryCode}
|
|
onEditValue={() => setCurrentStep('addPhoneNumber')}
|
|
value={addedPhoneNumberValue}
|
|
onPhoneNumberVerified={handlePhoneNumberVerified}
|
|
/>
|
|
)}
|
|
</>
|
|
);
|
|
};
|