fix: removes re-triggering of OTP provisioning (#14050)

Fixes : [13846 ](https://github.com/twentyhq/twenty/issues/13846)

---------

Co-authored-by: Paul Rastoin <45004772+prastoin@users.noreply.github.com>
Co-authored-by: Marie Stoppa <marie.stoppa@essec.edu>
This commit is contained in:
hc11h
2025-09-09 15:05:04 +05:30
committed by GitHub
parent fe27f321a9
commit ef68236735
3 changed files with 30 additions and 15 deletions
@@ -52,6 +52,7 @@ import { useOrigin } from '@/domain-manager/hooks/useOrigin';
import { useRedirect } from '@/domain-manager/hooks/useRedirect';
import { useRedirectToWorkspaceDomain } from '@/domain-manager/hooks/useRedirectToWorkspaceDomain';
import { domainConfigurationState } from '@/domain-manager/states/domainConfigurationState';
import { useLoadMockedObjectMetadataItems } from '@/object-metadata/hooks/useLoadMockedObjectMetadataItems';
import { useRefreshObjectMetadataItems } from '@/object-metadata/hooks/useRefreshObjectMetadataItems';
import { useLoadCurrentUser } from '@/users/hooks/useLoadCurrentUser';
import { workspaceAuthProvidersState } from '@/workspace/states/workspaceAuthProvidersState';
@@ -110,6 +111,7 @@ export const useAuth = () => {
const [, setSearchParams] = useSearchParams();
const navigate = useNavigate();
const { loadMockedObjectMetadataItems } = useLoadMockedObjectMetadataItems();
const clearSession = useRecoilCallback(
({ snapshot }) =>
@@ -171,9 +173,16 @@ export const useAuth = () => {
await client.clearStore();
// We need to explicitly clear the state to trigger the cookie deletion which include the parent domain
setLastAuthenticateWorkspaceDomain(null);
await loadMockedObjectMetadataItems();
navigate(AppPath.SignInUp);
},
[navigate, client, goToRecoilSnapshot, setLastAuthenticateWorkspaceDomain],
[
goToRecoilSnapshot,
client,
setLastAuthenticateWorkspaceDomain,
loadMockedObjectMetadataItems,
navigate,
],
);
const handleSetAuthTokens = useCallback(
@@ -1,24 +1,23 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { currentUserState } from '@/auth/states/currentUserState';
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
import { useLoadMockedObjectMetadataItems } from '@/object-metadata/hooks/useLoadMockedObjectMetadataItems';
import { useRefreshObjectMetadataItems } from '@/object-metadata/hooks/useRefreshObjectMetadataItems';
import { objectMetadataItemsState } from '@/object-metadata/states/objectMetadataItemsState';
import { isWorkspaceActiveOrSuspended } from 'twenty-shared/workspace';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
export const ObjectMetadataItemsLoadEffect = () => {
const currentUser = useRecoilValue(currentUserState);
const currentWorkspace = useRecoilValue(currentWorkspaceState);
const objectMetadataItems = useRecoilValue(objectMetadataItemsState);
const [isInitialized, setIsInitialized] = useState(false);
const { refreshObjectMetadataItems } = useRefreshObjectMetadataItems();
const { loadMockedObjectMetadataItems } = useLoadMockedObjectMetadataItems();
useEffect(() => {
if (objectMetadataItems.length > 0) {
if (isInitialized) {
return;
}
@@ -31,15 +30,16 @@ export const ObjectMetadataItemsLoadEffect = () => {
} else {
await refreshObjectMetadataItems();
}
setIsInitialized(true);
};
loadObjectMetadata();
}, [
currentUser,
currentWorkspace,
objectMetadataItems.length,
loadMockedObjectMetadataItems,
refreshObjectMetadataItems,
isInitialized,
]);
return <></>;
@@ -1,9 +1,10 @@
import { currentUserState } from '@/auth/states/currentUserState';
import { qrCodeState } from '@/auth/states/qrCode';
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
import { gql, useMutation } from '@apollo/client';
import { useLingui } from '@lingui/react/macro';
import { useEffect } from 'react';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared/utils';
const INITIATE_OTP_PROVISIONING_FOR_AUTHENTICATED_USER = gql`
@@ -16,8 +17,9 @@ const INITIATE_OTP_PROVISIONING_FOR_AUTHENTICATED_USER = gql`
export const TwoFactorAuthenticationSetupForSettingsEffect = () => {
const { enqueueErrorSnackBar } = useSnackBar();
const qrCode = useRecoilValue(qrCodeState);
const setQrCodeState = useSetRecoilState(qrCodeState);
const [qrCode, setQrCode] = useRecoilState(qrCodeState);
const currentUser = useRecoilValue(currentUserState);
const { t } = useLingui();
const [initiateOTPProvisioningForAuthenticatedUser] = useMutation(
@@ -25,7 +27,7 @@ export const TwoFactorAuthenticationSetupForSettingsEffect = () => {
);
useEffect(() => {
if (isDefined(qrCode)) {
if (!isDefined(currentUser) || isDefined(qrCode)) {
return;
}
@@ -41,7 +43,7 @@ export const TwoFactorAuthenticationSetupForSettingsEffect = () => {
throw new Error('No URI returned from OTP provisioning');
}
setQrCodeState(
setQrCode(
initiateOTPProvisioningResult.data
.initiateOTPProvisioningForAuthenticatedUser.uri,
);
@@ -57,10 +59,14 @@ export const TwoFactorAuthenticationSetupForSettingsEffect = () => {
};
handleTwoFactorAuthenticationProvisioningInitiation();
// Two factor authentication provisioning only needs to run once at mount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
}, [
enqueueErrorSnackBar,
initiateOTPProvisioningForAuthenticatedUser,
t,
setQrCode,
qrCode,
currentUser,
]);
return <></>;
};