diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts index 87298412e..ebd535b24 100644 --- a/apps/web/middleware.ts +++ b/apps/web/middleware.ts @@ -1,6 +1,8 @@ import type { NextRequest } from 'next/server'; import { NextResponse, URLPattern } from 'next/server'; +import type { UserResponse } from '@supabase/supabase-js'; + import { CsrfError, createCsrfProtect } from '@edge-csrf/nextjs'; import { checkRequiresMultiFactorAuthentication } from '@kit/supabase/check-requires-mfa'; @@ -20,12 +22,16 @@ export const config = { export async function middleware(request: NextRequest) { const response = NextResponse.next(); + const supabase = createMiddlewareClient(request, response); + + // get the user from the session (no matter if it's logged in or not) + const userResponse = await supabase.auth.getUser(); // set a unique request ID for each request // this helps us log and trace requests setRequestId(request); - // apply CSRF and session middleware + // apply CSRF protection for mutating requests const csrfResponse = await withCsrfMiddleware(request, response); // handle patterns for specific routes @@ -33,7 +39,11 @@ export async function middleware(request: NextRequest) { // if a pattern handler exists, call it if (handlePattern) { - const patternHandlerResponse = await handlePattern(request, csrfResponse); + const patternHandlerResponse = await handlePattern( + request, + csrfResponse, + userResponse, + ); // if a pattern handler returns a response, return it if (patternHandlerResponse) { @@ -41,7 +51,8 @@ export async function middleware(request: NextRequest) { } } - // if no pattern handler returned a response, return the session response + // if no pattern handler returned a response, + // return the session response return csrfResponse; } @@ -149,9 +160,13 @@ function getPatterns() { }, { pattern: new URLPattern({ pathname: '/home*' }), - handler: async (req: NextRequest, res: NextResponse) => { - const supabase = createMiddlewareClient(req, res); - const { data: user, error } = await supabase.auth.getUser(); + handler: async ( + req: NextRequest, + res: NextResponse, + userResponse: UserResponse, + ) => { + const { data: user, error } = userResponse; + const origin = req.nextUrl.origin; const next = req.nextUrl.pathname; @@ -163,6 +178,8 @@ function getPatterns() { return NextResponse.redirect(new URL(redirectPath, origin).href); } + const supabase = createMiddlewareClient(req, res); + const requiresMultiFactorAuthentication = await checkRequiresMultiFactorAuthentication(supabase); diff --git a/packages/supabase/src/hooks/use-auth-change-listener.ts b/packages/supabase/src/hooks/use-auth-change-listener.ts index 9cef5eb3d..3b98c18ea 100644 --- a/packages/supabase/src/hooks/use-auth-change-listener.ts +++ b/packages/supabase/src/hooks/use-auth-change-listener.ts @@ -34,7 +34,7 @@ export function useAuthChangeListener({ useEffect(() => { // keep this running for the whole session unless the component was unmounted - const listener = client.auth.onAuthStateChange((_, user) => { + const listener = client.auth.onAuthStateChange((event, user) => { // log user out if user is falsy // and if the current path is a private route const shouldRedirectUser = @@ -47,6 +47,10 @@ export function useAuthChangeListener({ return; } + if (event === 'SIGNED_OUT') { + return router.refresh(); + } + if (accessToken) { const isOutOfSync = user?.access_token !== accessToken; diff --git a/packages/supabase/src/hooks/use-sign-out.ts b/packages/supabase/src/hooks/use-sign-out.ts index bbf7be516..d8c2ad926 100644 --- a/packages/supabase/src/hooks/use-sign-out.ts +++ b/packages/supabase/src/hooks/use-sign-out.ts @@ -1,15 +1,13 @@ -import { useMutation, useQueryClient } from '@tanstack/react-query'; +import { useMutation } from '@tanstack/react-query'; import { useSupabase } from './use-supabase'; export function useSignOut() { const client = useSupabase(); - const queryClient = useQueryClient(); return useMutation({ mutationFn: async () => { await client.auth.signOut(); - await queryClient.invalidateQueries(); }, }); } diff --git a/packages/supabase/src/hooks/use-user.ts b/packages/supabase/src/hooks/use-user.ts index b9a6c9b96..0972999e2 100644 --- a/packages/supabase/src/hooks/use-user.ts +++ b/packages/supabase/src/hooks/use-user.ts @@ -14,7 +14,7 @@ export function useUser(initialData?: User | null) { // this is most likely a session error or the user is not logged in if (response.error) { - return null; + return undefined; } if (response.data?.user) { @@ -28,6 +28,7 @@ export function useUser(initialData?: User | null) { queryFn, queryKey, initialData, + refetchOnMount: false, refetchOnWindowFocus: false, }); }