diff --git a/apps/manager/src/app/api/auth/login/route.ts b/apps/manager/src/app/api/auth/login/route.ts index fe96a48b3..83addbb86 100644 --- a/apps/manager/src/app/api/auth/login/route.ts +++ b/apps/manager/src/app/api/auth/login/route.ts @@ -68,13 +68,18 @@ export async function POST(request: Request) { } const cookieStore = await cookies() - cookieStore.set("strapi-jwt", jwt, { - httpOnly: true, + const cookieOpts = { secure: process.env.NODE_ENV === "production", - sameSite: "lax", + sameSite: "lax" as const, path: "/", maxAge: 60 * 60 * 24 * 7, // 7 days - }) + } + cookieStore.set("strapi-jwt", jwt, { ...cookieOpts, httpOnly: true }) + cookieStore.set( + "manager-user", + JSON.stringify({ username: user.username, email: user.email }), + cookieOpts, + ) return NextResponse.json({ user: { id: user.id, email: user.email, role: user.role?.name }, diff --git a/apps/manager/src/app/api/auth/logout/route.ts b/apps/manager/src/app/api/auth/logout/route.ts index 045577984..9c6a29935 100644 --- a/apps/manager/src/app/api/auth/logout/route.ts +++ b/apps/manager/src/app/api/auth/logout/route.ts @@ -4,5 +4,6 @@ import { NextResponse } from "next/server" export async function POST() { const cookieStore = await cookies() cookieStore.delete("strapi-jwt") + cookieStore.delete("manager-user") return NextResponse.json({ success: true }) } diff --git a/apps/manager/src/app/dashboard/layout.tsx b/apps/manager/src/app/dashboard/layout.tsx index 7b0acf3d7..9e8b3e3d3 100644 --- a/apps/manager/src/app/dashboard/layout.tsx +++ b/apps/manager/src/app/dashboard/layout.tsx @@ -1,6 +1,7 @@ import type { Metadata } from "next" +import { cookies } from "next/headers" +import { redirect } from "next/navigation" import { DashboardNav } from "@/features/nav/dashboard-nav" -import { requireAuth } from "@/lib/require-auth" export const metadata: Metadata = { title: "Dashboard — VideoForge Manager", @@ -11,7 +12,27 @@ export default async function DashboardLayout({ }: { children: React.ReactNode }) { - const user = await requireAuth() + const cookieStore = await cookies() + const jwt = cookieStore.get("strapi-jwt")?.value + if (!jwt) { + redirect("/login") + } + + // Read display-only user info from cookie set at login. + // No Strapi call — avoids spurious logouts from transient upstream failures. + const raw = cookieStore.get("manager-user")?.value + let user = { username: "User", email: "" } + if (raw) { + try { + const parsed = JSON.parse(raw) as { username?: string; email?: string } + user = { + username: parsed.username ?? "User", + email: parsed.email ?? "", + } + } catch { + // Corrupted cookie — use defaults, don't block the page + } + } return (
diff --git a/apps/manager/src/lib/require-auth.ts b/apps/manager/src/lib/require-auth.ts deleted file mode 100644 index 482eaaa59..000000000 --- a/apps/manager/src/lib/require-auth.ts +++ /dev/null @@ -1,25 +0,0 @@ -// Server component authentication guard. -// Validates the Strapi JWT signature via /api/users/me and ensures the Manager role. -// Redirects to /login if authentication fails. - -import { cookies } from "next/headers" -import { redirect } from "next/navigation" -import { verifyStrapiJwtWithRole } from "@/lib/auth" - -type AuthUser = { username: string; email: string } - -export async function requireAuth(): Promise { - const cookieStore = await cookies() - const jwt = cookieStore.get("strapi-jwt")?.value - - if (!jwt) { - redirect("/login") - } - - const user = await verifyStrapiJwtWithRole(jwt) - if (!user || user.role?.name !== "Manager") { - redirect("/login") - } - - return { username: user.username, email: user.email } -}