diff --git a/app/client/[token]/page.tsx b/app/client/[token]/page.tsx index a39f7a9..5dd1df2 100644 --- a/app/client/[token]/page.tsx +++ b/app/client/[token]/page.tsx @@ -121,6 +121,15 @@ export default function ClientPortalPage({ const [sessionLabel, setSessionLabel] = useState(''); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [collapsedEpisodes, setCollapsedEpisodes] = useState>(new Set()); + + const toggleEpisode = (ep: string) => { + setCollapsedEpisodes((prev) => { + const next = new Set(prev); + if (next.has(ep)) next.delete(ep); else next.add(ep); + return next; + }); + }; useEffect(() => { params.then(({ token: t }) => { @@ -166,15 +175,6 @@ export default function ClientPortalPage({ ); } - const [collapsedEpisodes, setCollapsedEpisodes] = useState>(new Set()); - const toggleEpisode = (ep: string) => { - setCollapsedEpisodes((prev) => { - const next = new Set(prev); - if (next.has(ep)) next.delete(ep); else next.add(ep); - return next; - }); - }; - const allTasks = [...shots.flatMap((s) => s.tasks), ...assetTasks]; const totalTasks = allTasks.length; const approved = allTasks.filter( diff --git a/auth.config.ts b/auth.config.ts new file mode 100644 index 0000000..39757ea --- /dev/null +++ b/auth.config.ts @@ -0,0 +1,35 @@ +import type { NextAuthConfig } from "next-auth"; +import type { Role } from "@prisma/client"; + +/** + * Edge-safe auth config — no Prisma, no bcryptjs. + * Used by middleware (Edge Runtime) for JWT verification only. + * The full auth config (with Credentials provider + Prisma adapter) lives in auth.ts. + */ +export const authConfig: NextAuthConfig = { + session: { strategy: "jwt" }, + pages: { + signIn: "/login", + }, + callbacks: { + async jwt({ token, user }) { + if (user) { + token.id = user.id; + token.role = (user as { role: Role }).role; + token.mustChangePassword = + (user as { mustChangePassword?: boolean }).mustChangePassword ?? false; + } + return token; + }, + async session({ session, token }) { + if (token && session.user) { + session.user.id = token.id as string; + session.user.role = token.role as Role; + session.user.mustChangePassword = token.mustChangePassword as boolean; + } + return session; + }, + }, + // No providers here — Credentials provider (bcryptjs) only in auth.ts + providers: [], +}; diff --git a/auth.ts b/auth.ts index 16bb327..1609294 100644 --- a/auth.ts +++ b/auth.ts @@ -3,32 +3,11 @@ import { PrismaAdapter } from "@auth/prisma-adapter"; import Credentials from "next-auth/providers/credentials"; import { db } from "@/lib/db"; import bcrypt from "bcryptjs"; -import { Role } from "@prisma/client"; +import { authConfig } from "@/auth.config"; export const { handlers, auth, signIn, signOut } = NextAuth({ + ...authConfig, adapter: PrismaAdapter(db) as any, - session: { strategy: "jwt" }, - pages: { - signIn: "/login", - }, - callbacks: { - async jwt({ token, user }) { - if (user) { - token.id = user.id; - token.role = (user as { role: Role }).role; - token.mustChangePassword = (user as { mustChangePassword?: boolean }).mustChangePassword ?? false; - } - return token; - }, - async session({ session, token }) { - if (token && session.user) { - session.user.id = token.id as string; - session.user.role = token.role as Role; - session.user.mustChangePassword = token.mustChangePassword as boolean; - } - return session; - }, - }, providers: [ Credentials({ name: "credentials", diff --git a/middleware.ts b/middleware.ts index 1770d4b..35e24fc 100644 --- a/middleware.ts +++ b/middleware.ts @@ -1,6 +1,9 @@ -import { auth } from "@/auth"; +import NextAuth from "next-auth"; +import { authConfig } from "@/auth.config"; import { NextResponse } from "next/server"; +const { auth } = NextAuth(authConfig); + export default auth((req) => { const isLoggedIn = !!req.auth; const pathname = req.nextUrl.pathname;