Files
Todo/middleware.ts
Paul Bailey 895ceba55f 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
2025-12-02 00:39:04 +00:00

70 lines
2.2 KiB
TypeScript

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)$).*)",
],
}