From 05855413356f538b41a43935687a2abb0f5539f8 Mon Sep 17 00:00:00 2001 From: HoangPham <31430555+PhamAnhHoang@users.noreply.github.com> Date: Fri, 23 Feb 2024 17:37:14 +0700 Subject: [PATCH] Turn of 2fa platform --- apps/platform/src/hooks/use2FA.ts | 13 ++++- .../src/views/user /profile-security.view.tsx | 55 +++++++++++++++++-- libs/impl/src/constants/apiRoutes.ts | 1 + .../src/services/auth/twoFactor.service.ts | 13 ++++- 4 files changed, 74 insertions(+), 8 deletions(-) diff --git a/apps/platform/src/hooks/use2FA.ts b/apps/platform/src/hooks/use2FA.ts index c3956e0..c2f428a 100644 --- a/apps/platform/src/hooks/use2FA.ts +++ b/apps/platform/src/hooks/use2FA.ts @@ -6,7 +6,8 @@ import { turnOn2FAStep2Service, auth2FAService, authDisableService, - Recover2FAData + Recover2FAData, + turnOff2FA2Service } from '@isomera/impl' import useSession from './useSession' @@ -41,16 +42,24 @@ const useTwoFactorAuthHook = () => { } ) + const { mutateAsync: turnOff2FA, isLoading: isLoadingTurnOf2FA } = + useMutation(async (data: Pure) => { + const response = await turnOff2FA2Service(data) + return response + }) + return { generate2FA, verify2FA, authenticate, disable2FA, + turnOff2FA, isLoading: isLoadingGenerate || isLoadingVerify || isLoadingAuthenticate || - isLoadingDisable + isLoadingDisable || + isLoadingTurnOf2FA } } diff --git a/apps/platform/src/views/user /profile-security.view.tsx b/apps/platform/src/views/user /profile-security.view.tsx index a4f51f6..c69855f 100644 --- a/apps/platform/src/views/user /profile-security.view.tsx +++ b/apps/platform/src/views/user /profile-security.view.tsx @@ -1,9 +1,11 @@ import React, { useEffect, useState } from 'react' import useSession from '../../hooks/useSession' import { useTwoFactorAuthHook } from '../../hooks/use2FA' +import { setAuthState } from '@isomera/impl' +import { UserInterface } from '@isomera/interfaces' export const UserSecurityView: React.FC = () => { - const { generate2FA, verify2FA, isLoading } = useTwoFactorAuthHook() + const { generate2FA, verify2FA, turnOff2FA, isLoading } = useTwoFactorAuthHook() const [qrCodeImage, setQrCodeImage] = useState(null) const [code, setCode] = useState('') const [verificationError, setVerificationError] = useState( @@ -14,7 +16,8 @@ export const UserSecurityView: React.FC = () => { recoveryCodes, updateRecoveryCodes, recoveryViewed, - updateRecoveryViewed + updateRecoveryViewed, + setUser } = useSession() const [showRecoveryCodes, setShowRecoveryCodes] = useState(false) @@ -58,8 +61,8 @@ export const UserSecurityView: React.FC = () => { const handle2FAToggleChange = ( event: React.ChangeEvent ) => { + setIsTwoFAEnabled(event.target.checked) if (!isTwoFAEnabled) { - setIsTwoFAEnabled(event.target.checked) handleToggle2FA() } } @@ -82,6 +85,28 @@ export const UserSecurityView: React.FC = () => { } } + const handleTurnoff2FA = async (e: React.FormEvent) => { + e.preventDefault() + try { + const codeNoSpace = code.split(' ').join('') + const {status, access_token, refresh_token} = await turnOff2FA({ code: codeNoSpace }) + if (status === 'ok') { + setCode('') + setAuthState({accessToken: access_token, refreshToken: refresh_token}) + const newUser = {...user} + newUser.isTwoFAEnabled = false + newUser.accessToken = access_token + newUser.refreshToken = refresh_token + setUser(newUser as UserInterface) + } else { + setVerificationError('Failed to verify 2FA code.') + } + } catch (error) { + console.error('Error verifying 2FA code:', error) + setVerificationError('An error occurred while verifying the 2FA code.') + } + } + useEffect(() => { if (user) { setIsTwoFAEnabled(user.isTwoFAEnabled) @@ -97,11 +122,33 @@ export const UserSecurityView: React.FC = () => { type="checkbox" checked={isTwoFAEnabled} onChange={handle2FAToggleChange} - disabled={isLoading || isTwoFAEnabled} + disabled={isLoading} /> {isTwoFAEnabled ? '2FA Enabled' : 'Enable 2FA'} )} + { + user?.isTwoFAEnabled && !isTwoFAEnabled && ( +
+
+ +
+ + {verificationError && ( +

{verificationError}

+ )} +
+ ) + } {qrCodeImage && ( <>

diff --git a/libs/impl/src/constants/apiRoutes.ts b/libs/impl/src/constants/apiRoutes.ts index 665f3f2..d6ffc48 100644 --- a/libs/impl/src/constants/apiRoutes.ts +++ b/libs/impl/src/constants/apiRoutes.ts @@ -24,6 +24,7 @@ export const API_AUTH_2FA_STEP_2 = 'auth/2fa/turn-on' export const API_AUTH_2FA_STEP_3 = 'auth/2fa/authenticate' export const API_AUTH_2FA_RECOVER = 'auth/2fa/request-recovery' export const API_AUTH_2FA_CONFIRM_RECOVERY = 'auth/2fa/confirm-recovery' +export const API_AUTH_2FA_TURN_OFF = 'auth/2fa/turn-off' // User diff --git a/libs/impl/src/services/auth/twoFactor.service.ts b/libs/impl/src/services/auth/twoFactor.service.ts index 94461aa..10e18c5 100644 --- a/libs/impl/src/services/auth/twoFactor.service.ts +++ b/libs/impl/src/services/auth/twoFactor.service.ts @@ -1,10 +1,11 @@ -import { UserInterface } from '@isomera/interfaces' +import { TurnOff2FAResponseInterface, UserInterface } from '@isomera/interfaces' import { API_AUTH_2FA_CONFIRM_RECOVERY, API_AUTH_2FA_RECOVER, API_AUTH_2FA_STEP_1, API_AUTH_2FA_STEP_2, - API_AUTH_2FA_STEP_3 + API_AUTH_2FA_STEP_3, + API_AUTH_2FA_TURN_OFF } from '../../constants' import { axiosInstance } from '../../utils' @@ -74,3 +75,11 @@ export const authDisableService = async ( return response.data } + +export const turnOff2FA2Service = async ( + data: Verify2FAData +): Promise => { + const response = await axiosInstance.post(API_AUTH_2FA_TURN_OFF, data) + + return response.data +}