chore: auth factory

This commit is contained in:
2025-08-25 23:42:29 +03:30
parent ad88aa893f
commit d1cadad183
4 changed files with 69 additions and 25 deletions

View File

@@ -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<AuthMode>('register');
const [authType, setAuthType] = useState<AuthType>('phone');
const [currentStep, setCurrentStep] = useState<AuthStep>('emailOrPhone');
@@ -30,6 +30,33 @@ export const AuthenticationSteps = (): JSX.Element => {
const [addedPhoneNumberValue, setAddedPhoneNumberValue] =
useState<string>('');
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);
}
}
};

View File

@@ -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);

View File

@@ -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<AuthType>;
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<HTMLDivElement>(null);

View File

@@ -8,3 +8,10 @@ export type AuthStep =
| 'enterPassword'
| 'addPhoneNumber'
| 'addedPhoneNumberVerify';
export interface AuthFactory {
clientId: string;
redirectUrl: string | null;
accountsApplication: boolean;
getFullRedirectUrl: (token: string) => string;
}