Implement session management (Task 5)
- Configure JWT session strategy with 30-day expiration - Implement session validation middleware for route protection - Create logout functionality with session termination - Handle session expiration automatically via JWT - Add session helper functions (getCurrentSession, isAuthenticated) - Protect routes: /, /list/*, /profile/*, /invitations/* - Redirect unauthenticated users to login with callback URL - Requirements: 2.4, 2.5, 3.1, 3.2, 3.4
This commit is contained in:
69
middleware.ts
Normal file
69
middleware.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { auth } from "@/auth"
|
||||
import { NextResponse } from "next/server"
|
||||
import type { NextRequest } from "next/server"
|
||||
|
||||
/**
|
||||
* Middleware for session validation and route protection
|
||||
*
|
||||
* This middleware:
|
||||
* - Validates session tokens on protected routes
|
||||
* - Redirects unauthenticated users to login
|
||||
* - Handles session expiration
|
||||
* - Allows access to auth pages for unauthenticated users
|
||||
*/
|
||||
export default auth((req) => {
|
||||
const { nextUrl } = req
|
||||
const isLoggedIn = !!req.auth?.user
|
||||
|
||||
// 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")
|
||||
|
||||
// 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")) {
|
||||
return NextResponse.redirect(new URL("/", req.url))
|
||||
}
|
||||
return NextResponse.next()
|
||||
}
|
||||
|
||||
// Redirect to login if accessing protected route without authentication
|
||||
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)
|
||||
return NextResponse.redirect(loginUrl)
|
||||
}
|
||||
|
||||
// Allow access to public routes
|
||||
return NextResponse.next()
|
||||
})
|
||||
|
||||
/**
|
||||
* 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)$).*)",
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user