- 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.
78 lines
2.7 KiB
TypeScript
78 lines
2.7 KiB
TypeScript
import NextAuth from "next-auth"
|
|
import { authConfig } from "@/auth.config"
|
|
|
|
/**
|
|
* Middleware for session validation, route protection, and security headers
|
|
*
|
|
* This middleware:
|
|
* - Validates session tokens on protected routes
|
|
* - Redirects unauthenticated users to login
|
|
* - Handles session expiration
|
|
* - Allows access to auth pages for unauthenticated users
|
|
* - Adds security headers (CSRF protection, XSS protection, etc.)
|
|
*
|
|
* Requirements: 3.3, 3.5, 9.4 (CSRF protection), 9.5 (security headers)
|
|
*/
|
|
const { auth } = NextAuth(authConfig)
|
|
|
|
export default auth((req) => {
|
|
// The authorization logic is handled in auth.config.ts authorized callback
|
|
// Here we just add security headers
|
|
|
|
const requestHeaders = new Headers(req.headers)
|
|
|
|
// Add security headers - Requirement 9.4, 9.5
|
|
// CSRF Protection - SameSite cookie attribute is set in auth.ts
|
|
// This header provides additional CSRF protection
|
|
requestHeaders.set('X-Content-Type-Options', 'nosniff')
|
|
|
|
// XSS Protection
|
|
requestHeaders.set('X-XSS-Protection', '1; mode=block')
|
|
|
|
// Prevent clickjacking attacks
|
|
requestHeaders.set('X-Frame-Options', 'DENY')
|
|
|
|
// Referrer Policy - don't leak referrer information
|
|
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
|
|
const csp = [
|
|
"default-src 'self'",
|
|
"script-src 'self' 'unsafe-inline' 'unsafe-eval'", // unsafe-inline and unsafe-eval needed for Next.js
|
|
"style-src 'self' 'unsafe-inline'", // unsafe-inline needed for Tailwind
|
|
"img-src 'self' data: blob:",
|
|
"font-src 'self' data:",
|
|
"connect-src 'self'",
|
|
"frame-ancestors 'none'",
|
|
].join('; ')
|
|
requestHeaders.set('Content-Security-Policy', csp)
|
|
|
|
// Permissions Policy - restrict access to browser features
|
|
requestHeaders.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=()')
|
|
|
|
return undefined // Let NextAuth handle the response
|
|
})
|
|
|
|
/**
|
|
* Matcher configuration for middleware
|
|
* Applies middleware to all routes except:
|
|
* - API routes (handled separately)
|
|
* - Static files (_next/static)
|
|
* - Image optimization (_next/image)
|
|
* - Favicon and other public assets
|
|
*/
|
|
export const config = {
|
|
matcher: [
|
|
/*
|
|
* Match all request paths except for the ones starting with:
|
|
* - api (API routes)
|
|
* - _next/static (static files)
|
|
* - _next/image (image optimization files)
|
|
* - favicon.ico (favicon file)
|
|
* - public assets (images, icons, manifest, sw.js)
|
|
*/
|
|
"/((?!api|_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp|ico|json|js)$).*)",
|
|
],
|
|
}
|