diff --git a/src/app/api/auth/[...nextauth]/options.ts b/src/app/api/auth/[...nextauth]/options.ts index 4807815..f651357 100644 --- a/src/app/api/auth/[...nextauth]/options.ts +++ b/src/app/api/auth/[...nextauth]/options.ts @@ -2,7 +2,9 @@ import type { NextAuthOptions } from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import { getUserByEmailServer } from "@api/user/utils"; import { compare } from "bcryptjs"; -import { User } from "@prisma/client"; +import { User, PrismaClient } from "@prisma/client"; + +const prisma = new PrismaClient(); export const options: NextAuthOptions = { providers: [ @@ -30,20 +32,62 @@ export const options: NextAuthOptions = { // Docs: https://next-auth.js.org/configuration/providers/credentials const user: User | null = await getUserByEmailServer(email); - + // Check if user exists and if password matches if (!user) { throw new Error("Invalid user"); } - if (user && (await compare(password, user.password))) { - return user; // Authentication successful - } else { + + if (!(await compare(password, user.password))) { throw new Error("Invalid password"); } + + let volunteerDetails = null; + if (user.role !== "ADMIN") { + console.log("HERE!"); + volunteerDetails = await prisma.volunteerDetails.findUnique({ + where: { userId: user.id }, + }); + console.log(volunteerDetails); + } + + return { + id: user.id, + role: user.role, + firstName: user.firstName, + lastName: user.lastName, + email: user.email, + volunteerDetails, + }; }, }), ], pages: { signIn: "/public/signIn", }, + callbacks: { + async jwt({ token, user }) { + console.log({ token, user }); + if (user) { + token.id = user.id; + token.role = user.role; + token.firstName = user.firstName; + token.lastName = user.lastName; + + if (user.role !== "ADMIN") { + token.volunteerDetails = user.volunteerDetails || null; + } + } + return token; + }, + async session({ session, token }) { + console.log({ session, token }); + session.user.id = token.id; + session.user.role = token.role; + session.user.firstName = token.firstName; + session.user.lastName = token.lastName; + session.user.volunteerDetails = token.volunteerDetails || null; + return session; + }, + }, }; diff --git a/src/app/private/page.tsx b/src/app/private/page.tsx index c5f16d2..e52d425 100644 --- a/src/app/private/page.tsx +++ b/src/app/private/page.tsx @@ -1,7 +1,20 @@ +"use client"; + +import { useSession } from "next-auth/react"; + export default function HomePage() { + const { data: session } = useSession(); + + if (!session) { + return

You are not logged in.

; + } + + console.log(session.user); + return (

Home Page

+
Welcome, {session.user?.firstName || "User"}!
); } diff --git a/src/components/Login.tsx b/src/components/Login.tsx index b31a440..69dbd96 100644 --- a/src/components/Login.tsx +++ b/src/components/Login.tsx @@ -143,7 +143,10 @@ export default function LoginForm() { sx={{ color: "#667085" }} /> - diff --git a/src/components/SideNavBar.tsx b/src/components/SideNavBar.tsx index 3996208..b8e333d 100644 --- a/src/components/SideNavBar.tsx +++ b/src/components/SideNavBar.tsx @@ -65,7 +65,7 @@ const SideNavBar = ({ role }: SideNavBarProps) => { }`} onClick={() => tab.name === "Logout" - ? signOut({ callbackUrl: "/public/signin" }) + ? signOut({ callbackUrl: "/public/signIn" }) : router.replace(tab.href) } > diff --git a/src/middleware.ts b/src/middleware.ts index 188a98a..c1cb423 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -1,11 +1,21 @@ -import { withAuth } from "next-auth/middleware"; // Import withAuth from next-auth +import { getToken } from "next-auth/jwt"; +import { NextRequest, NextResponse } from "next/server"; -export default withAuth({ - pages: { - signIn: "/api/auth/signin", // Redirect to this page if not authenticated - }, -}); +export async function middleware(request: NextRequest) { + const token = await getToken({ req: request }); + const { pathname } = request.nextUrl; + + if ((pathname.startsWith("/private") || pathname === "/") && !token) { + return NextResponse.redirect(new URL("/public/signIn", request.url)); + } + + if ((pathname.startsWith("/public") || pathname === "/") && token) { + return NextResponse.redirect(new URL("/private", request.url)); + } + + return NextResponse.next(); +} export const config = { - matcher: ["/"], // Protect these routes + matcher: ["/", "/private/:path*", "/public/:path*"], // Protect these routes }; diff --git a/src/types/next-auth.d.ts b/src/types/next-auth.d.ts new file mode 100644 index 0000000..d95c7e2 --- /dev/null +++ b/src/types/next-auth.d.ts @@ -0,0 +1,47 @@ +import "next-auth"; + +declare module "next-auth" { + interface Session { + user: { + id: string; + role: "VOLUNTEER" | "ADMIN"; + firstName: string; + lastName: string; + email: string; + volunteerDetails?: VolunteerDetails | null; + }; + } + + interface User { + id: string; + role: "VOLUNTEER" | "ADMIN"; + firstName: string; + lastName: string; + email: string; + volunteerDetails?: VolunteerDetails | null; + } +} + +declare module "next-auth/jwt" { + interface JWT { + id: string; + role: "VOLUNTEER" | "ADMIN"; + firstName: string; + lastName: string; + email: string; + volunteerDetails?: VolunteerDetails | null; + } +} + +interface VolunteerDetails { + ageOver14: boolean; + country: string; + address: string; + city: string; + state: string; + zipCode: string; + hasLicense: boolean; + speaksEsp: boolean; + volunteerType: string; + hoursWorked: number; +}