feat: google authentication added
This commit is contained in:
2
.env
2
.env
@@ -1,4 +1,4 @@
|
|||||||
VITE_GOOGLE_CLIENT_ID=https://272098283932-bft2gvlgjn8edopg0lnqjq1i9ekdmipt.apps.googleusercontent.com
|
VITE_GOOGLE_CLIENT_ID=272098283932-bft2gvlgjn8edopg0lnqjq1i9ekdmipt.apps.googleusercontent.com
|
||||||
VITE_DEFUALT_AUTH_RETURN_URL=/setting/profile
|
VITE_DEFUALT_AUTH_RETURN_URL=/setting/profile
|
||||||
VITE_APP_URL=https://accounts.business-harmony.com
|
VITE_APP_URL=https://accounts.business-harmony.com
|
||||||
VITE_API_URL=https://accounts.business-harmony.com/api
|
VITE_API_URL=https://accounts.business-harmony.com/api
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
|
<script src="https://accounts.google.com/gsi/client" async defer></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ export interface GoogleAuthenticationProps {
|
|||||||
) => void;
|
) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated use V2 instead
|
||||||
|
*/
|
||||||
export const GoogleAuthentication = ({
|
export const GoogleAuthentication = ({
|
||||||
disabled,
|
disabled,
|
||||||
authFactory,
|
authFactory,
|
||||||
@@ -44,11 +47,8 @@ export const GoogleAuthentication = ({
|
|||||||
document.body.appendChild(script);
|
document.body.appendChild(script);
|
||||||
|
|
||||||
script.onload = () => {
|
script.onload = () => {
|
||||||
clientRef.current = google.accounts.oauth2.initCodeClient({
|
clientRef.current = google.accounts.id.initialize({
|
||||||
client_id: import.meta.env.VITE_GOOGLE_CLIENT_ID,
|
client_id: import.meta.env.VITE_GOOGLE_CLIENT_ID,
|
||||||
scope: 'openid email profile',
|
|
||||||
ux_mode: 'popup',
|
|
||||||
response_type: 'code',
|
|
||||||
callback: async (resp: GoogleCodeClientResponse) => {
|
callback: async (resp: GoogleCodeClientResponse) => {
|
||||||
const apiRequest: LoginOrSignUpWithGoogleRequest = {
|
const apiRequest: LoginOrSignUpWithGoogleRequest = {
|
||||||
idToken: resp.id_token,
|
idToken: resp.id_token,
|
||||||
@@ -88,6 +88,7 @@ export const GoogleAuthentication = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
|
type="button"
|
||||||
onClick={handleGoogleLogin}
|
onClick={handleGoogleLogin}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
loading={loginWithGoogleLoading}
|
loading={loginWithGoogleLoading}
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import { useEffect, useRef } from 'react';
|
||||||
|
import type {
|
||||||
|
LoginOrSignUpWithGoogleRequest,
|
||||||
|
LoginResult,
|
||||||
|
} from '../../types/userTypes';
|
||||||
|
import type { AuthFactory } from '../../types/authTypes';
|
||||||
|
import {
|
||||||
|
generateTokenWithGoogle,
|
||||||
|
type GenerateTokenResponse,
|
||||||
|
} from '../../api/identityAPI';
|
||||||
|
import { loginOrSignUpWithGoogle } from '../../api/authorizationAPI';
|
||||||
|
import { useApi } from '@/hooks/useApi';
|
||||||
|
import { Icon, useToast } from '@rkheftan/harmony-ui';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { Box, Button } from '@mui/material';
|
||||||
|
import { Google } from 'iconsax-react';
|
||||||
|
|
||||||
|
interface GoogleAuthenticationV2Props {
|
||||||
|
disabled: boolean;
|
||||||
|
authFactory: AuthFactory;
|
||||||
|
onGoogleAuthenticated: (
|
||||||
|
loginResult: LoginResult,
|
||||||
|
tokenResponse: GenerateTokenResponse,
|
||||||
|
) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const GoogleAuthenticationV2 = ({
|
||||||
|
disabled,
|
||||||
|
authFactory,
|
||||||
|
onGoogleAuthenticated,
|
||||||
|
}: GoogleAuthenticationV2Props) => {
|
||||||
|
const toast = useToast();
|
||||||
|
const { t } = useTranslation('authentication');
|
||||||
|
const { loading: loginWithGoogleLoading, execute: loginWithGoogleCall } =
|
||||||
|
useApi(loginOrSignUpWithGoogle);
|
||||||
|
const googleButtonRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const initializeData = {
|
||||||
|
client_id: import.meta.env.VITE_GOOGLE_CLIENT_ID,
|
||||||
|
callback: handleCredentialResponse,
|
||||||
|
};
|
||||||
|
|
||||||
|
google.accounts.id.initialize(initializeData);
|
||||||
|
|
||||||
|
google.accounts.id.renderButton(
|
||||||
|
document.getElementById('google-signin-button'),
|
||||||
|
{ theme: 'outline' },
|
||||||
|
);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleCredentialResponse = async (response: { credential: any }) => {
|
||||||
|
const idToken = response.credential;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const apiRequest: LoginOrSignUpWithGoogleRequest = {
|
||||||
|
idToken: idToken,
|
||||||
|
returnUrl: authFactory.redirectUrl,
|
||||||
|
};
|
||||||
|
const res = await loginWithGoogleCall(apiRequest);
|
||||||
|
|
||||||
|
if (!res) return;
|
||||||
|
|
||||||
|
if (res.success) {
|
||||||
|
const tokenRes = await generateTokenWithGoogle({
|
||||||
|
...apiRequest,
|
||||||
|
client_id: authFactory.clientId,
|
||||||
|
});
|
||||||
|
|
||||||
|
onGoogleAuthenticated(res, tokenRes.data);
|
||||||
|
} else {
|
||||||
|
toast({
|
||||||
|
message: t('loginForm.googleAuthenticationFailed'),
|
||||||
|
severity: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
toast({
|
||||||
|
message: t('loginForm.googleAuthenticationFailed'),
|
||||||
|
severity: 'error',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleGoogleLogin = () => {
|
||||||
|
if (googleButtonRef.current) {
|
||||||
|
const googleCustomRenderedDivs =
|
||||||
|
googleButtonRef.current.querySelectorAll('div');
|
||||||
|
|
||||||
|
googleCustomRenderedDivs.forEach((b) => b.click());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Box sx={{ display: 'none !important' }}>
|
||||||
|
<div ref={googleButtonRef} id="google-signin-button"></div>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={handleGoogleLogin}
|
||||||
|
disabled={disabled}
|
||||||
|
loading={loginWithGoogleLoading}
|
||||||
|
variant="outlined"
|
||||||
|
startIcon={<Icon Component={Google} variant="Bold" />}
|
||||||
|
>
|
||||||
|
{t('loginForm.loginWithGoogle')}
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -9,11 +9,11 @@ import { CountryCodeSelector } from '../CountryCodeSelector';
|
|||||||
import type { LoginResult, UserStatus } from '../../types/userTypes';
|
import type { LoginResult, UserStatus } from '../../types/userTypes';
|
||||||
import { getUserStatusByPhoneNumberOrEmail } from '../../api/authorizationAPI';
|
import { getUserStatusByPhoneNumberOrEmail } from '../../api/authorizationAPI';
|
||||||
import type { CountryCode } from '@/types/commonTypes';
|
import type { CountryCode } from '@/types/commonTypes';
|
||||||
import { GoogleAuthentication } from './GoogleAuthentication';
|
|
||||||
import { isPhoneNumber } from '@/utils/regexes/isValidPhoneNumber';
|
import { isPhoneNumber } from '@/utils/regexes/isValidPhoneNumber';
|
||||||
import { useToast } from '@rkheftan/harmony-ui';
|
import { useToast } from '@rkheftan/harmony-ui';
|
||||||
import { useApi } from '@/hooks/useApi';
|
import { useApi } from '@/hooks/useApi';
|
||||||
import type { GenerateTokenResponse } from '../../api/identityAPI';
|
import type { GenerateTokenResponse } from '../../api/identityAPI';
|
||||||
|
import { GoogleAuthenticationV2 } from './GoogleAuthenticationV2';
|
||||||
|
|
||||||
export interface LoginRegisterFormProps {
|
export interface LoginRegisterFormProps {
|
||||||
loginRegisterValue: string;
|
loginRegisterValue: string;
|
||||||
@@ -173,7 +173,7 @@ export function LoginRegisterForm({
|
|||||||
{t('loginForm.submitButton')}
|
{t('loginForm.submitButton')}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<GoogleAuthentication
|
<GoogleAuthenticationV2
|
||||||
authFactory={authFactory}
|
authFactory={authFactory}
|
||||||
onGoogleAuthenticated={onGoogleAuthenticated}
|
onGoogleAuthenticated={onGoogleAuthenticated}
|
||||||
disabled={userStatusLoading}
|
disabled={userStatusLoading}
|
||||||
|
|||||||
Reference in New Issue
Block a user