From d4d4f3a8e5baf77d52184fba8feb1d9492650f7a Mon Sep 17 00:00:00 2001 From: Andrej Date: Sun, 5 Jan 2025 14:19:39 +0100 Subject: [PATCH] refactor: :recycle: cleaning up auth flow --- apps/api/src/index.ts | 8 ++----- apps/web/src/components/auth/sign-in-form.tsx | 5 ++++- apps/web/src/components/auth/sign-up-form.tsx | 5 ++++- .../common/sidebar/sign-out-button.tsx | 6 +++++ .../providers/auth-provider/index.tsx | 4 ++-- apps/web/src/hooks/queries/use-get-me.ts | 6 +++-- apps/web/src/routes/dashboard/index.tsx | 12 ++++++---- apps/web/src/routes/index.tsx | 22 +------------------ 8 files changed, 31 insertions(+), 37 deletions(-) diff --git a/apps/api/src/index.ts b/apps/api/src/index.ts index 18be604..3930905 100644 --- a/apps/api/src/index.ts +++ b/apps/api/src/index.ts @@ -9,9 +9,7 @@ const app = new Elysia() .guard({ async beforeHandle({ set, cookie: { session } }) { if (!session?.value) { - set.status = "Unauthorized"; - - return set.status; + return { user: null, session: null }; } const { user, session: validatedSession } = await validateSessionToken( @@ -19,9 +17,7 @@ const app = new Elysia() ); if (!user || !validatedSession) { - set.status = "Unauthorized"; - - return set.status; + return { user: null, session: null }; } }, }) diff --git a/apps/web/src/components/auth/sign-in-form.tsx b/apps/web/src/components/auth/sign-in-form.tsx index f4c31d5..e0add88 100644 --- a/apps/web/src/components/auth/sign-in-form.tsx +++ b/apps/web/src/components/auth/sign-in-form.tsx @@ -15,6 +15,7 @@ import { AlertCircle, Eye, EyeOff } from "lucide-react"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { type ZodType, z } from "zod"; +import useAuth from "../providers/auth-provider/hooks/use-auth"; import { Alert, AlertDescription, AlertTitle } from "../ui/alert"; export type SignInFormValues = { @@ -30,6 +31,7 @@ const signInSchema: ZodType = z.object({ export function SignInForm() { const [showPassword, setShowPassword] = useState(false); const { history } = useRouter(); + const { setUser } = useAuth(); const form = useForm({ resolver: zodResolver(signInSchema), defaultValues: { @@ -43,7 +45,8 @@ export function SignInForm() { }); const onSubmit = async () => { - await mutateAsync(); + const { data: user } = await mutateAsync(); + setUser(user); history.push("/dashboard"); }; diff --git a/apps/web/src/components/auth/sign-up-form.tsx b/apps/web/src/components/auth/sign-up-form.tsx index a28d6ba..8ec7943 100644 --- a/apps/web/src/components/auth/sign-up-form.tsx +++ b/apps/web/src/components/auth/sign-up-form.tsx @@ -15,6 +15,7 @@ import { AlertCircle, Eye, EyeOff } from "lucide-react"; import { useState } from "react"; import { useForm } from "react-hook-form"; import { type ZodType, z } from "zod"; +import useAuth from "../providers/auth-provider/hooks/use-auth"; import { Alert, AlertDescription, AlertTitle } from "../ui/alert"; export type SignUpFormValues = { @@ -31,6 +32,7 @@ const signUpSchema: ZodType = z.object({ export function SignUpForm() { const [showPassword, setShowPassword] = useState(false); + const { setUser } = useAuth(); const { history } = useRouter(); const form = useForm({ resolver: zodResolver(signUpSchema), @@ -47,7 +49,8 @@ export function SignUpForm() { }); const onSubmit = async () => { - await mutateAsync(); + const { data: user } = await mutateAsync(); + setUser(user); history.push("/dashboard"); }; diff --git a/apps/web/src/components/common/sidebar/sign-out-button.tsx b/apps/web/src/components/common/sidebar/sign-out-button.tsx index 93c273c..02c4b59 100644 --- a/apps/web/src/components/common/sidebar/sign-out-button.tsx +++ b/apps/web/src/components/common/sidebar/sign-out-button.tsx @@ -1,15 +1,21 @@ import useAuth from "@/components/providers/auth-provider/hooks/use-auth"; import useSignOut from "@/hooks/mutations/use-sign-out"; +import { useQueryClient } from "@tanstack/react-query"; import { useRouter } from "@tanstack/react-router"; import { LogOut } from "lucide-react"; function SignOutButton() { const { setUser } = useAuth(); const { mutateAsync, isPending } = useSignOut(); + const queryClient = useQueryClient(); const { history } = useRouter(); const handleSignOut = async () => { await mutateAsync(); + queryClient.invalidateQueries({ + queryKey: ["me"], + type: "all", + }); setUser(null); history.push("/auth/sign-in"); }; diff --git a/apps/web/src/components/providers/auth-provider/index.tsx b/apps/web/src/components/providers/auth-provider/index.tsx index f3bed7c..a2caf0a 100644 --- a/apps/web/src/components/providers/auth-provider/index.tsx +++ b/apps/web/src/components/providers/auth-provider/index.tsx @@ -25,7 +25,7 @@ function AuthProvider({ children }: PropsWithChildren) { createdAt: Date; } | null>(null); - const { data, isLoading } = useGetMe(); + const { data, isFetching } = useGetMe(user?.id); useEffect(() => { if (data) { @@ -33,7 +33,7 @@ function AuthProvider({ children }: PropsWithChildren) { } }, [data]); - if (isLoading) { + if (isFetching) { return (
diff --git a/apps/web/src/hooks/queries/use-get-me.ts b/apps/web/src/hooks/queries/use-get-me.ts index e3d99d7..d242f7b 100644 --- a/apps/web/src/hooks/queries/use-get-me.ts +++ b/apps/web/src/hooks/queries/use-get-me.ts @@ -1,9 +1,11 @@ import me from "@/fetchers/user/me"; import { useQuery } from "@tanstack/react-query"; -function useGetMe() { +function useGetMe(userId: string | undefined) { + console.log({ userId }); + return useQuery({ - queryKey: ["me"], + queryKey: ["me", userId], queryFn: () => me(), retry: 0, }); diff --git a/apps/web/src/routes/dashboard/index.tsx b/apps/web/src/routes/dashboard/index.tsx index c24dd6d..6c51a72 100644 --- a/apps/web/src/routes/dashboard/index.tsx +++ b/apps/web/src/routes/dashboard/index.tsx @@ -1,12 +1,16 @@ import { Sidebar } from "@/components/common/sidebar"; +import { redirect } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router"; export const Route = createFileRoute("/dashboard/")({ component: DashboardIndexRouteComponent, - loader: ({ context: { queryClient } }) => - queryClient.ensureQueryData({ - queryKey: ["me"], - }), + async beforeLoad({ context: { user } }) { + if (!user) { + throw redirect({ + to: "/auth/sign-in", + }); + } + }, }); function DashboardIndexRouteComponent() { diff --git a/apps/web/src/routes/index.tsx b/apps/web/src/routes/index.tsx index ad754ee..5d70dd0 100644 --- a/apps/web/src/routes/index.tsx +++ b/apps/web/src/routes/index.tsx @@ -1,23 +1,3 @@ -import type { User } from "@/types/user"; -import { redirect } from "@tanstack/react-router"; import { createFileRoute } from "@tanstack/react-router"; -export const Route = createFileRoute("/")({ - async beforeLoad({ context: { queryClient } }) { - const { data: user } = await queryClient.ensureQueryData<{ - data: User; - }>({ - queryKey: ["me"], - }); - - if (!user) { - throw redirect({ - to: "/auth/sign-in", - }); - } - - throw redirect({ - to: "/dashboard", - }); - }, -}); +export const Route = createFileRoute("/")();