-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmiddleware.ts
74 lines (61 loc) · 2.54 KB
/
middleware.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
// Cache for session checks to avoid repeated cookie parsing
const sessionCache = new Map<string, boolean>();
export function middleware(request: NextRequest) {
// Create a unique key for this request based on URL and cookies
const cookiesStr = request.cookies.toString();
const requestId = request.url + (cookiesStr || "");
// Check if we've already determined authentication for this request
if (sessionCache.has(requestId)) {
const isAuthenticated = sessionCache.get(requestId);
// Fast path for authenticated users
if (isAuthenticated &&
(request.nextUrl.pathname === "/login" || request.nextUrl.pathname === "/verify") &&
!request.nextUrl.search.includes("error=")) {
return NextResponse.redirect(new URL("/dashboard", request.url));
}
// Fast path for unauthenticated users
if (!isAuthenticated && request.nextUrl.pathname.startsWith("/dashboard")) {
const loginUrl = new URL("/login", request.url);
loginUrl.searchParams.set("callbackUrl", request.url);
return NextResponse.redirect(loginUrl);
}
return NextResponse.next();
}
// Check if user is authenticated by looking for the session cookie
const isAuthenticated = request.cookies.has("next-auth.session-token") ||
request.cookies.has("__Secure-next-auth.session-token");
// Cache the result for future requests
sessionCache.set(requestId, isAuthenticated);
// Limit cache size to prevent memory leaks
if (sessionCache.size > 100) {
const firstKey = sessionCache.keys().next().value;
if (firstKey) {
sessionCache.delete(firstKey);
}
}
// Only protect dashboard routes
if (!isAuthenticated && request.nextUrl.pathname.startsWith("/dashboard")) {
const loginUrl = new URL("/login", request.url);
loginUrl.searchParams.set("callbackUrl", request.url);
return NextResponse.redirect(loginUrl);
}
// Only redirect from login/verify pages if authenticated
if (isAuthenticated &&
(request.nextUrl.pathname === "/login" || request.nextUrl.pathname === "/verify") &&
!request.nextUrl.search.includes("error=")) {
return NextResponse.redirect(new URL("/dashboard", request.url));
}
return NextResponse.next();
}
// Only apply middleware to these specific routes
export const config = {
matcher: [
// Protected routes
"/dashboard/:path*",
// Auth pages (but not API routes or error pages)
"/login",
"/verify"
],
};