Skip to content

Commit db646c2

Browse files
committed
refactor: prevent using middleware to improve static route
1 parent 84c50c4 commit db646c2

9 files changed

Lines changed: 57 additions & 152 deletions

File tree

app/(admin)/layout.tsx

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { AppSidebar } from "@/components/app-sidebar";
22
import { SidebarInset, SidebarProvider } from "@/components/ui/sidebar";
3+
import ProtectedRoute from "@/providers/use-protected-route";
34
import { unstable_ViewTransition as ViewTransition } from "react";
45

56
export default function AdminLayout({
@@ -8,20 +9,22 @@ export default function AdminLayout({
89
children: React.ReactNode;
910
}>) {
1011
return (
11-
<SidebarProvider
12-
style={{
13-
"--sidebar-width": "calc(var(--spacing) * 72)",
14-
"--header-height": "calc(var(--spacing) * 12)",
15-
} as React.CSSProperties}
16-
>
17-
<AppSidebar variant="inset" />
18-
<SidebarInset>
19-
<ViewTransition>
20-
<div suppressHydrationWarning>
21-
{children}
22-
</div>
23-
</ViewTransition>
24-
</SidebarInset>
25-
</SidebarProvider>
12+
<ProtectedRoute>
13+
<SidebarProvider
14+
style={{
15+
"--sidebar-width": "calc(var(--spacing) * 72)",
16+
"--header-height": "calc(var(--spacing) * 12)",
17+
} as React.CSSProperties}
18+
>
19+
<AppSidebar variant="inset" />
20+
<SidebarInset>
21+
<ViewTransition>
22+
<div suppressHydrationWarning>
23+
{children}
24+
</div>
25+
</ViewTransition>
26+
</SidebarInset>
27+
</SidebarProvider>
28+
</ProtectedRoute>
2629
);
2730
}

app/forbidden.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import ForbiddenLayout from "@/components/forbidden-layout/page";
2+
import type { Metadata } from "next";
3+
4+
export const metadata: Metadata = {
5+
title: "權限不足",
6+
}
7+
8+
export default function ForbiddenPage() {
9+
return <ForbiddenLayout />;
10+
}

app/unauthorized.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { redirect } from "next/navigation";
2+
3+
export default async function UnauthorizedPage() {
4+
redirect("/login");
5+
}
Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,11 @@
11
import { Logo } from "@/components/logo";
22
import { Button } from "@/components/ui/button";
33
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
4-
import { redirectIfAuthenticated } from "@/lib/auth.rsc";
54
import { AlertTriangle } from "lucide-react";
65
import Link from "next/link";
76
import { UserInfo } from "./user-info";
87

9-
import type { Metadata } from "next";
10-
export const metadata: Metadata = {
11-
title: "權限不足",
12-
};
13-
14-
export default async function ForbiddenPage() {
15-
await redirectIfAuthenticated();
16-
8+
export default async function ForbiddenLayout() {
179
return (
1810
<div
1911
className={`

components/login-form.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
44
import { cn } from "@/lib/utils";
55
import { AlertCircle, CheckCircle } from "lucide-react";
66

7-
interface LoginFormProps extends React.ComponentProps<"div"> {
7+
export interface LoginFormProps extends React.ComponentProps<"div"> {
88
error?: string;
99
errorDescription?: string;
1010
message?: string;

middleware.ts

Lines changed: 0 additions & 127 deletions
This file was deleted.

next.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const nextConfig: NextConfig = {
1111
],
1212
ppr: "incremental",
1313
turbopackPersistentCaching: true,
14+
authInterrupts: true,
1415
},
1516
};
1617

providers/use-protected-route.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
"use server";
2+
3+
import { getAuthStatus, getAuthToken } from "@/lib/auth";
4+
import { forbidden, unauthorized } from "next/navigation";
5+
6+
export default async function ProtectedRoute({ children }: { children: React.ReactNode }) {
7+
const token = await getAuthToken();
8+
if (!token) {
9+
unauthorized();
10+
}
11+
12+
const { loggedIn, role } = await getAuthStatus(token);
13+
if (!loggedIn) {
14+
unauthorized();
15+
}
16+
if (role !== "admin") {
17+
forbidden();
18+
}
19+
20+
return children;
21+
}

0 commit comments

Comments
 (0)