Refactor authentication system: replace NextAuth with custom login/logout/session handling, improve cookie management, and enhance error handling
Build and Push Reader Image / docker (push) Successful in 39s

This commit is contained in:
2026-04-24 01:53:32 +07:00
parent 690a2fbd51
commit 7c4404ded8
26 changed files with 368 additions and 239 deletions
+2
View File
@@ -6,6 +6,8 @@ import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { toast } from "sonner"
// Trang này được đặt dưới /mod layout đã kiểm soát quyền ở server side.
type NovelRow = {
id: string
title: string
+2 -7
View File
@@ -1,13 +1,8 @@
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/lib/auth"
import { redirect } from "next/navigation"
import { requireModSessionUser } from "@/lib/server-auth"
import { EditorClient } from "./editor-client"
export default async function ModEditChapterPage({ params }: { params: Promise<{ id: string }> }) {
const session = await getServerSession(authOptions)
if (!session || (session.user.role !== "MOD" && session.user.role !== "ADMIN")) {
redirect("/")
}
await requireModSessionUser()
const resolvedParams = await params
+2 -7
View File
@@ -1,13 +1,8 @@
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/lib/auth"
import { redirect } from "next/navigation"
import { requireModSessionUser } from "@/lib/server-auth"
import { ChapterClient } from "./chapter-client"
export default async function ModChuongPage() {
const session = await getServerSession(authOptions)
if (!session || (session.user.role !== "MOD" && session.user.role !== "ADMIN")) {
redirect("/")
}
await requireModSessionUser()
return <ChapterClient />
}
+2 -7
View File
@@ -1,13 +1,8 @@
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/lib/auth"
import { redirect } from "next/navigation"
import { requireModSessionUser } from "@/lib/server-auth"
import { RecommendationClient } from "./recommendation-client"
export default async function ModRecommendationPage() {
const session = await getServerSession(authOptions)
if (!session || (session.user.role !== "MOD" && session.user.role !== "ADMIN")) {
redirect("/")
}
await requireModSessionUser()
return <RecommendationClient />
}
+2 -9
View File
@@ -1,6 +1,4 @@
import { redirect } from "next/navigation"
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/lib/auth"
import { requireModSessionUser } from "@/lib/server-auth"
import { CollapsibleSidebar } from "./collapsible-sidebar"
export default async function ModLayout({
@@ -8,12 +6,7 @@ export default async function ModLayout({
}: {
children: React.ReactNode
}) {
const session = await getServerSession(authOptions)
// Kiểm tra quyền
if (!session || (session.user.role !== "MOD" && session.user.role !== "ADMIN")) {
redirect("/") // Không đủ quyền, đưa về trang chủ
}
await requireModSessionUser()
return (
<div className="flex min-h-[calc(100vh-3.5rem)] bg-muted/20">
+6 -6
View File
@@ -1,13 +1,13 @@
import { getServerSession } from "next-auth"
import { authOptions } from "@/lib/auth"
import Link from "next/link"
import { Sparkles } from "lucide-react"
import { cookies } from "next/headers"
import { AUTH_COOKIE_NAME } from "@/lib/auth-cookie"
import { requireModSessionUser } from "@/lib/server-auth"
const readerApiOrigin = (process.env.READER_API_ORIGIN || "http://localhost:8000").replace(/\/+$/, "")
export default async function ModDashboardPage() {
const session = await getServerSession(authOptions)
const sessionUser = await requireModSessionUser()
let novelCount = 0
let totalViews = 0
@@ -15,10 +15,10 @@ export default async function ModDashboardPage() {
let seriesCount = 0
try {
const cookieHeader = (await cookies()).toString()
const accessToken = (await cookies()).get(AUTH_COOKIE_NAME)?.value || ""
const res = await fetch(`${readerApiOrigin}/api/mod/overview`, {
cache: "no-store",
headers: cookieHeader ? { cookie: cookieHeader } : undefined,
headers: accessToken ? { authorization: `Bearer ${accessToken}` } : undefined,
})
if (res.ok) {
const data = await res.json()
@@ -33,7 +33,7 @@ export default async function ModDashboardPage() {
return (
<div>
<h1 className="text-2xl font-bold mb-4">Xin chào, {session?.user.name}</h1>
<h1 className="text-2xl font-bold mb-4">Xin chào, {sessionUser?.name || "Moderator"}</h1>
<p className="text-muted-foreground mb-6">
Chào mừng bạn đến với trang quản trị dành cho Moderator.
</p>
+2 -7
View File
@@ -1,13 +1,8 @@
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/lib/auth"
import { redirect } from "next/navigation"
import { requireModSessionUser } from "@/lib/server-auth"
import { SeriesClient } from "./series-client"
export default async function ModSeriesPage() {
const session = await getServerSession(authOptions)
if (!session || (session.user.role !== "MOD" && session.user.role !== "ADMIN")) {
redirect("/")
}
await requireModSessionUser()
return <SeriesClient />
}
+2 -7
View File
@@ -1,13 +1,8 @@
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/lib/auth"
import { redirect } from "next/navigation"
import { requireModSessionUser } from "@/lib/server-auth"
import { GenreClient } from "./genre-client"
export default async function ModTheLoaiPage() {
const session = await getServerSession(authOptions)
if (!session || (session.user.role !== "MOD" && session.user.role !== "ADMIN")) {
redirect("/")
}
await requireModSessionUser()
return <GenreClient />
}
+2 -8
View File
@@ -1,14 +1,8 @@
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/lib/auth"
import { redirect } from "next/navigation"
import { requireModSessionUser } from "@/lib/server-auth"
import { MissingFieldsClient } from "./missing-fields-client"
export default async function ModMissingFieldsPage() {
const session = await getServerSession(authOptions)
if (!session || (session.user.role !== "MOD" && session.user.role !== "ADMIN")) {
redirect("/")
}
await requireModSessionUser()
return <MissingFieldsClient />
}
+2 -7
View File
@@ -1,13 +1,8 @@
import { getServerSession } from "next-auth/next"
import { authOptions } from "@/lib/auth"
import { redirect } from "next/navigation"
import { requireModSessionUser } from "@/lib/server-auth"
import { NovelClient } from "./novel-client"
export default async function ModTruyenPage() {
const session = await getServerSession(authOptions)
if (!session || (session.user.role !== "MOD" && session.user.role !== "ADMIN")) {
redirect("/")
}
await requireModSessionUser()
return <NovelClient />
}