From cb4146fa3573fe531c40cfdcc36a6c4212aef5cf Mon Sep 17 00:00:00 2001 From: admin Date: Thu, 2 Oct 2025 08:30:45 +0700 Subject: [PATCH] 251002 frontend/app/(protected)/layout.jsx --- frontend/app/layout.jsx | 156 ++++++++++++++++++++-------------------- 1 file changed, 79 insertions(+), 77 deletions(-) diff --git a/frontend/app/layout.jsx b/frontend/app/layout.jsx index d491c3e7..b748dd72 100755 --- a/frontend/app/layout.jsx +++ b/frontend/app/layout.jsx @@ -1,31 +1,33 @@ -// File: frontend/app/layout.jsx +// frontend/app/layout.jsx +import "./globals.css"; import Link from "next/link"; import { redirect } from "next/navigation"; import { cookies, headers } from "next/headers"; -// ถ้ามี lib rbac เดิมอยู่ให้ใช้ต่อได้ -import { can } from "@/lib/rbac"; -// แก้ title ให้ถูกสะกด -export const metadata = { title: "DMS | Protected" }; +export const metadata = { + title: "DMS", + description: "Document Management System — LCBP3 Phase 3", +}; const API_BASE = (process.env.NEXT_PUBLIC_API_BASE || "").replace(/\/$/, ""); -async function fetchSessionFromAPI() { - // ดึงคุกกี้จริงจากฝั่งเซิร์ฟเวอร์ แล้วส่งต่อให้ backend - const cookieHeader = cookies().toString(); // serialize ทั้งชุด - const hostHdr = headers().get("host"); - const protoHdr = headers().get("x-forwarded-proto") || "https"; +/** ดึงสถานะผู้ใช้แบบ global (ไม่บังคับล็อกอิน) */ +async function fetchGlobalSession() { + const cookieStore = await cookies(); + const cookieHeader = cookieStore.toString(); + + const hdrs = await headers(); + const hostHdr = hdrs.get("host"); + const protoHdr = hdrs.get("x-forwarded-proto") || "https"; const res = await fetch(`${API_BASE}/api/auth/me`, { method: "GET", headers: { Cookie: cookieHeader, - // เผื่อ backend ตรวจ origin/proto/host "X-Forwarded-Host": hostHdr || "", "X-Forwarded-Proto": protoHdr, Accept: "application/json", }, - // server component ไม่ต้องใช้ credentials cache: "no-store", }); @@ -38,75 +40,75 @@ async function fetchSessionFromAPI() { } } -export default async function ProtectedLayout({ children }) { - const session = await fetchSessionFromAPI(); - if (!session) { - // พยายามส่ง next path กลับไปที่ /login - redirect("/login?next=/dashboard"); - } - const { user } = session; +/** ปุ่ม Logout แบบ Server Action (ไม่ต้องมี client component) */ +async function LogoutAction() { + "use server"; + const cookieStore = await cookies(); + const cookieHeader = cookieStore.toString(); + + const hdrs = await headers(); + const hostHdr = hdrs.get("host"); + const protoHdr = hdrs.get("x-forwarded-proto") || "https"; + + // เรียก backend ให้ลบคุกกี้ออก (HttpOnly cookies) + await fetch(`${API_BASE}/api/auth/logout`, { + method: "POST", + headers: { + Cookie: cookieHeader, + "X-Forwarded-Host": hostHdr || "", + "X-Forwarded-Proto": protoHdr, + Accept: "application/json", + }, + cache: "no-store", + }); + + // กลับไปหน้า login พร้อม next ไป dashboard + redirect("/login?next=/dashboard"); +} + +export default async function RootLayout({ children }) { + const session = await fetchGlobalSession(); + const loggedIn = !!session?.user; return ( -
- + + -
- {/* System / Quick Actions */} -
-
Document Management System — LCBP3 Phase 3
- - {can(user, "admin:view") && ( - Admin - )} - {can(user, "users:manage") && ( - ผู้ใช้/บทบาท - )} - {can(user, "health:view") && ( - Health - )} - {can(user, "workflow:view") && ( - Workflow - )} - {can(user, "rfa:create") && ( - + RFA - )} - {can(user, "drawing:upload") && ( - + Upload Drawing - )} - {can(user, "transmittal:create") && ( - + Transmittal - )} - {can(user, "correspondence:create") && ( - + หนังสือสื่อสาร - )} -
- - {children} -
-
+
{children}
+ + ); -} \ No newline at end of file +}