Skip to content

Commit

Permalink
[auth] Fixe les boucles de redirection + l'état d'utilisateur connect…
Browse files Browse the repository at this point in the history
…é sans DCP
  • Loading branch information
farnoux committed Jun 24, 2024
1 parent 8267935 commit cbf5b7f
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {TAuthContext, UserData} from 'core-logic/api/auth/AuthProvider';
import DropdownFloater from 'ui/shared/floating-ui/DropdownFloater';
import {HeaderPropsWithModalState} from './types';
import './MenuUtilisateur.css';
import {useQuery} from '../../../core-logic/hooks/query';
import {useQueryClient} from 'react-query';

/**
* Affiche le menu associé à l'utilisateur courant
Expand Down Expand Up @@ -90,6 +92,7 @@ const MenuUtilisateurBtn = forwardRef(
*/
const Deconnexion = ({auth}: {auth: TAuthContext}) => {
const history = useHistory();
const queryClient = useQueryClient();
return (
<Link
className="fr-nav__link"
Expand All @@ -98,6 +101,11 @@ const Deconnexion = ({auth}: {auth: TAuthContext}) => {
to="/"
onClick={() => {
auth.disconnect().then(() => {
// Supprime le cache de la session
queryClient.removeQueries({
queryKey: ['session'],
});

history.push('/');
});
}}
Expand Down
29 changes: 6 additions & 23 deletions app.territoiresentransitions.react/src/app/Redirector.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
import {useEffect} from 'react';
import {useHistory, useLocation} from 'react-router-dom';
import {homePath, makeCollectiviteAccueilUrl, signUpPath} from 'app/paths';
import {useAuth, useDCP} from 'core-logic/api/auth/AuthProvider';
import {getAuthPaths} from '@tet/api';
import {homePath, makeCollectiviteAccueilUrl} from 'app/paths';
import {useAuth} from 'core-logic/api/auth/AuthProvider';
import {
acceptAgentInvitation,
useInvitationState,
} from 'core-logic/hooks/useInvitationState';
import {useOwnedCollectivites} from 'core-logic/hooks/useOwnedCollectivites';
import {getAuthPaths} from '@tet/api';
import {useEffect} from 'react';
import {useHistory, useLocation} from 'react-router-dom';

export const Redirector = () => {
const history = useHistory();
const {pathname} = useLocation();
const {isConnected, user} = useAuth();
const {data: DCP, isLoading: isLoadingDCP} = useDCP(user?.id);
const {isConnected} = useAuth();
const {invitationId, invitationEmail, consume} = useInvitationState();
const userCollectivites = useOwnedCollectivites();
const isLandingConnected = isConnected && pathname === '/'; // L'utilisateur est connecté et arrive sur '/'.
Expand Down Expand Up @@ -72,21 +71,5 @@ export const Redirector = () => {
}
}, [isConnected, invitationId]);

// redirige vers l'étape 3 de la création de compte si il manque des infos aux DCP
const userInfoRequired =
isConnected &&
user?.id &&
!isLoadingDCP &&
(DCP === null || !DCP?.nom || !DCP?.prenom);
/* TODO: ajouter la condition suivante pour rendre obligatoire la saisie
du numéro de tél si il est absent de la base (mais il faudra alors ajouter
le pré-remplissage du formulaire avec les DCP déjà complétées)
|| !DCP?.telephone*/
useEffect(() => {
if (userInfoRequired) {
document.location.replace(`${signUpPath}&view=etape3`);
}
}, [userInfoRequired]);

return null;
};
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import {useQuery} from 'react-query';
import {clearAuthTokens, getRootDomain, setAuthTokens} from '@tet/api';
import {supabaseClient} from '../supabase';
import {useCurrentSession} from './useCurrentSession';
import {signUpPath} from 'app/paths';
import {dcpFetch} from '@tet/api/dist/src/utilisateurs/shared/data_access/dcp.fetch';

// typage du contexte exposé par le fournisseur
export type TAuthContext = {
Expand Down Expand Up @@ -46,7 +48,7 @@ export const AuthProvider = ({children}: {children: ReactNode}) => {
const [authError, setAuthError] = useState<string | null>(null);

// charge les données associées à l'utilisateur courant
const {data: dcp} = useDCP(user?.id);
const {data: dcp, isLoading: isLoadingDCP} = useDCP(user?.id);
const {data: isSupport} = useIsSupport(user?.id);
const userData = useMemo(
() => (user && dcp ? {...user, ...dcp, isSupport} : null),
Expand Down Expand Up @@ -125,6 +127,12 @@ export const AuthProvider = ({children}: {children: ReactNode}) => {
const isConnected = Boolean(user);
const value = {connect, disconnect, user: userData, authError, isConnected};

// Redirige l'utilisateur vers la page d'authentification si nécessaire
const userInfoRequired = session && !isLoadingDCP && !dcp;
if (userInfoRequired) {
document.location.replace(`${signUpPath}&view=etape3`);
}

return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};

Expand Down Expand Up @@ -161,20 +169,11 @@ const clearCrispUserData = () => {
}
};

// lecture des DCP
const fetchDCP = async (user_id: string) => {
const {data} = await supabaseClient
.from('dcp')
.select('user_id,nom,prenom,telephone,cgu_acceptees_le')
.match({user_id});

return data?.length ? data[0] : null;
};

// hook qui utilise les queries DCP
export const useDCP = (user_id?: string) => {
// fetch
return useQuery(['dcp', user_id], () => (user_id ? fetchDCP(user_id) : null));
return useQuery(['dcp', user_id], () =>
user_id ? dcpFetch({dbClient: supabaseClient, user_id}) : null
);
};

// vérifie si l'utilisateur courant à le droit "support"
Expand Down
16 changes: 16 additions & 0 deletions packages/api/src/utilisateurs/shared/data_access/dcp.fetch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import {DBClient} from '../../../typeUtils';

export const dcpFetch = async ({
dbClient,
user_id,
}: {
dbClient: DBClient;
user_id: string;
}) => {
const {data} = await dbClient
.from('dcp')
.select('user_id,nom,prenom,telephone,cgu_acceptees_le')
.match({user_id});

return data?.length ? data[0] : null;
};
10 changes: 5 additions & 5 deletions packages/auth/app/signup/useSignupState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,11 @@ export const useSignupState = ({
if (view === 'etape3') {
// enregistre les DCP
const {data} = await supabase.auth.getSession();
const user_id = data.session?.user?.id;
if (user_id) {
const email = defaultValues?.email || formData?.email;
const {telephone, prenom, nom} = formData as SignupDataStep3;
const user_id = data.session?.user.id;
const email = data.session?.user.email;

if (!email) return;
if (user_id && email) {
const {telephone, prenom, nom} = formData as SignupDataStep3;

const {error} = await supabase.from('dcp').insert([
{
Expand All @@ -131,6 +130,7 @@ export const useSignupState = ({
user_id,
},
]);

// et l'acceptation des CGU
const {error: error2} = await supabase.rpc('accepter_cgu');

Expand Down
43 changes: 38 additions & 5 deletions packages/auth/components/Login/useRedirectTo.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,49 @@
import {getAppBaseUrl, restoreSessionFromAuthTokens} from '@tet/api';
import {dcpFetch} from '@tet/api/dist/src/utilisateurs/shared/data_access/dcp.fetch';
import {RedirectType, redirect, useRouter} from 'next/navigation';
import {useEffect} from 'react';
import {restoreSessionFromAuthTokens} from '@tet/api';
import {supabase} from 'src/clientAPI';

// redirige sur l'url donnée si la session de l'utilisateur peut être restaurée depuis les cookies
export const useRedirectTo = (redirectTo: string) => {
const router = useRouter();

useEffect(() => {
const restore = async () => {
const ret = await restoreSessionFromAuthTokens(supabase);
if (ret?.data?.session) {
document.location.replace(redirectTo);
const sessionData = await restoreSessionFromAuthTokens(supabase);
const user = sessionData?.data.user;

if (!user) {
return;
}

const dcpData = await dcpFetch({
dbClient: supabase,
user_id: user.id,
});

if (user && !dcpData) {
const searchParams = new URLSearchParams({redirect_to: redirectTo});
router.replace(`/signup?view=etape3&${searchParams}`);
return;
}

if (redirectTo.startsWith('/')) {
const url = getAppBaseUrl(window.location.hostname) + redirectTo;
router.replace(url);
return;
}

if (nestPasUneUrlAuth(redirectTo)) {
router.replace(redirectTo);
return;
}
};
restore();
}, [redirectTo]);
}, [redirectTo, router]);
};

function nestPasUneUrlAuth(url: string) {
const authOrigin = window.document.location.origin;
return !url.startsWith(authOrigin);
}

0 comments on commit cbf5b7f

Please sign in to comment.