fix: Resolve Prisma Edge Runtime error in middleware

- Move all auth configuration to auth.config.ts to avoid Prisma imports in Edge Runtime
- Update middleware to use NextAuth with edge-compatible config
- Consolidate session, cookies, and callback configuration in auth.config.ts
- Update auth.ts to extend authConfig and only add Prisma-dependent providers
- This fixes the 'PrismaClient is not configured to run in Edge Runtime' error

The middleware now properly works with NextAuth v5 beta without trying to load Prisma in the Edge Runtime.
This commit is contained in:
2025-12-02 01:38:26 +00:00
parent 0e609af924
commit 11c4411f68
3 changed files with 66 additions and 99 deletions

View File

@@ -1,6 +1,5 @@
import { auth } from "@/auth"
import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"
import NextAuth from "next-auth"
import { authConfig } from "@/auth.config"
/**
* Middleware for session validation, route protection, and security headers
@@ -14,59 +13,27 @@ import type { NextRequest } from "next/server"
*
* Requirements: 3.3, 3.5, 9.4 (CSRF protection), 9.5 (security headers)
*/
const { auth } = NextAuth(authConfig)
export default auth((req) => {
const { nextUrl } = req
const isLoggedIn = !!req.auth?.user
// The authorization logic is handled in auth.config.ts authorized callback
// Here we just add security headers
// Define protected routes
const isProtectedRoute =
nextUrl.pathname === "/" ||
nextUrl.pathname.startsWith("/list") ||
nextUrl.pathname.startsWith("/profile") ||
nextUrl.pathname.startsWith("/invitations")
// Define auth pages (login, register, etc.)
const isAuthPage = nextUrl.pathname.startsWith("/auth")
// Create response
let response: NextResponse
// Allow access to auth pages regardless of authentication status
if (isAuthPage) {
// If already logged in and trying to access login/register, redirect to home
if (isLoggedIn && (nextUrl.pathname === "/auth/login" || nextUrl.pathname === "/auth/register")) {
response = NextResponse.redirect(new URL("/", req.url))
} else {
response = NextResponse.next()
}
}
// Redirect to login if accessing protected route without authentication
else if (isProtectedRoute && !isLoggedIn) {
const loginUrl = new URL("/auth/login", req.url)
// Add callback URL to redirect back after login
loginUrl.searchParams.set("callbackUrl", nextUrl.pathname)
response = NextResponse.redirect(loginUrl)
}
// Allow access to public routes
else {
response = NextResponse.next()
}
const requestHeaders = new Headers(req.headers)
// Add security headers - Requirement 9.4, 9.5
const headers = response.headers
// CSRF Protection - SameSite cookie attribute is set in auth.ts
// This header provides additional CSRF protection
headers.set('X-Content-Type-Options', 'nosniff')
requestHeaders.set('X-Content-Type-Options', 'nosniff')
// XSS Protection
headers.set('X-XSS-Protection', '1; mode=block')
requestHeaders.set('X-XSS-Protection', '1; mode=block')
// Prevent clickjacking attacks
headers.set('X-Frame-Options', 'DENY')
requestHeaders.set('X-Frame-Options', 'DENY')
// Referrer Policy - don't leak referrer information
headers.set('Referrer-Policy', 'strict-origin-when-cross-origin')
requestHeaders.set('Referrer-Policy', 'strict-origin-when-cross-origin')
// Content Security Policy - helps prevent XSS attacks
// Note: This is a basic CSP. You may need to adjust based on your needs
@@ -79,12 +46,12 @@ export default auth((req) => {
"connect-src 'self'",
"frame-ancestors 'none'",
].join('; ')
headers.set('Content-Security-Policy', csp)
requestHeaders.set('Content-Security-Policy', csp)
// Permissions Policy - restrict access to browser features
headers.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=()')
requestHeaders.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=()')
return response
return undefined // Let NextAuth handle the response
})
/**