UNAUTHORIZED gmail error (#12262)
# Gmail OAuth authentication flow issues ### TLDR This error is not an error and therefore should be treated as a simple redirect with a snackbar. ### More details Fixing incomplete OAuth token exchange processes and improving error handling for empty Gmail inboxes. The changes include modifications to OAuth guards, to ensure that if a user clicks "cancel" instead of completing the authentication workflow if fails ## Before: Redirection from `/settings/accounts` to `app.twenty.com` with an `UNAUTHORIZED` error ## After : <img width="948" alt="Screenshot 2025-05-26 at 18 04 37" src="https://github.com/user-attachments/assets/62c8721e-c2b3-4e3d-ad0b-e4059dfb7a98" /> Fixes https://github.com/twentyhq/twenty/issues/11895 --------- Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
@ -8,6 +8,7 @@ import { ChromeExtensionSidecarProvider } from '@/chrome-extension-sidecar/compo
|
||||
import { ClientConfigProvider } from '@/client-config/components/ClientConfigProvider';
|
||||
import { ClientConfigProviderEffect } from '@/client-config/components/ClientConfigProviderEffect';
|
||||
import { MainContextStoreProvider } from '@/context-store/components/MainContextStoreProvider';
|
||||
import { ErrorMessageEffect } from '@/error-handler/components/ErrorMessageEffect';
|
||||
import { PromiseRejectionEffect } from '@/error-handler/components/PromiseRejectionEffect';
|
||||
import { ApolloMetadataClientProvider } from '@/object-metadata/components/ApolloMetadataClientProvider';
|
||||
import { ObjectMetadataItemsLoadEffect } from '@/object-metadata/components/ObjectMetadataItemsLoadEffect';
|
||||
@ -49,6 +50,7 @@ export const AppRouterProviders = () => {
|
||||
<PrefetchDataProvider>
|
||||
<UserThemeProviderEffect />
|
||||
<SnackBarProvider>
|
||||
<ErrorMessageEffect />
|
||||
<DialogManagerScope dialogManagerScopeId="dialog-manager">
|
||||
<DialogManager>
|
||||
<StrictMode>
|
||||
|
||||
@ -5,8 +5,6 @@ import { useIsLogged } from '@/auth/hooks/useIsLogged';
|
||||
import { useVerifyLogin } from '@/auth/hooks/useVerifyLogin';
|
||||
import { clientConfigApiStatusState } from '@/client-config/states/clientConfigApiStatusState';
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
@ -14,9 +12,7 @@ import { useNavigateApp } from '~/hooks/useNavigateApp';
|
||||
export const VerifyLoginTokenEffect = () => {
|
||||
const [searchParams] = useSearchParams();
|
||||
const loginToken = searchParams.get('loginToken');
|
||||
const errorMessage = searchParams.get('errorMessage');
|
||||
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
const isLogged = useIsLogged();
|
||||
const navigate = useNavigateApp();
|
||||
const { verifyLoginToken } = useVerifyLogin();
|
||||
@ -26,13 +22,6 @@ export const VerifyLoginTokenEffect = () => {
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (isDefined(errorMessage)) {
|
||||
enqueueSnackBar(errorMessage, {
|
||||
dedupeKey: 'get-auth-tokens-from-login-token-failed-dedupe-key',
|
||||
variant: SnackBarVariant.Error,
|
||||
});
|
||||
}
|
||||
|
||||
if (!clientConfigLoaded) return;
|
||||
|
||||
if (isDefined(loginToken)) {
|
||||
|
||||
@ -0,0 +1,26 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
|
||||
export const ErrorMessageEffect = () => {
|
||||
const { enqueueSnackBar } = useSnackBar();
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const errorMessage = searchParams.get('errorMessage');
|
||||
|
||||
useEffect(() => {
|
||||
if (isDefined(errorMessage)) {
|
||||
enqueueSnackBar(errorMessage, {
|
||||
dedupeKey: 'error-message-dedupe-key',
|
||||
variant: SnackBarVariant.Error,
|
||||
});
|
||||
const newSearchParams = new URLSearchParams(searchParams);
|
||||
newSearchParams.delete('errorMessage');
|
||||
setSearchParams(newSearchParams);
|
||||
}
|
||||
}, [enqueueSnackBar, errorMessage, searchParams, setSearchParams]);
|
||||
|
||||
return <></>;
|
||||
};
|
||||
Reference in New Issue
Block a user