feat: Implement Next.js middleware for authentication and add a new API endpoint to fetch user details.

This commit is contained in:
Timo 2026-01-01 20:43:50 +01:00
parent c2988f1d50
commit a15e3b67c2
2 changed files with 49 additions and 54 deletions

View File

@ -2,6 +2,9 @@ import { NextRequest, NextResponse } from 'next/server';
import { cookies } from 'next/headers'; import { cookies } from 'next/headers';
import { db } from '@/lib/db'; import { db } from '@/lib/db';
// Force dynamic rendering (required for cookies)
export const dynamic = 'force-dynamic';
/** /**
* GET /api/user * GET /api/user
* Get current user information * Get current user information

View File

@ -1,64 +1,56 @@
import { withAuth } from 'next-auth/middleware';
import { NextResponse } from 'next/server'; import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export default withAuth( export function middleware(req: NextRequest) {
function middleware(req) { const path = req.nextUrl.pathname;
const token = req.nextauth.token;
const path = req.nextUrl.pathname;
// Protected dashboard routes - redirect to /signup if not authenticated // Public routes that don't require authentication
const protectedRoutes = [ const publicPaths = [
'/dashboard', '/',
'/create', '/pricing',
'/bulk-creation', '/faq',
'/analytics', '/blog',
'/pricing', '/login',
'/settings', '/signup',
]; '/privacy',
'/newsletter',
];
// Check if current path matches any protected route // Check if path is public
const isProtectedRoute = protectedRoutes.some(route => path.startsWith(route)); const isPublicPath = publicPaths.some(p => path === p || path.startsWith(p + '/'));
// If protected route and no token, redirect to signup
if (isProtectedRoute && !token) {
const signupUrl = new URL('/signup', req.url);
return NextResponse.redirect(signupUrl);
}
// Allow API routes
if (path.startsWith('/api/')) {
return NextResponse.next(); return NextResponse.next();
},
{
callbacks: {
authorized: ({ req, token }) => {
// Public routes that don't require authentication
const publicPaths = [
'/',
'/pricing',
'/faq',
'/blog',
'/login',
'/signup',
'/api/auth',
];
const path = req.nextUrl.pathname;
// Allow public paths
if (publicPaths.some(p => path.startsWith(p))) {
return true;
}
// Allow redirect routes
if (path.startsWith('/r/')) {
return true;
}
// Require authentication for all other routes
return !!token;
},
},
} }
);
// Allow redirect routes (QR code redirects)
if (path.startsWith('/r/')) {
return NextResponse.next();
}
// Allow static files
if (path.includes('.') || path.startsWith('/_next')) {
return NextResponse.next();
}
// Allow public paths
if (isPublicPath) {
return NextResponse.next();
}
// For protected routes, check for userId cookie
const userId = req.cookies.get('userId')?.value;
if (!userId) {
// Not authenticated - redirect to signup
const signupUrl = new URL('/signup', req.url);
return NextResponse.redirect(signupUrl);
}
// Authenticated - allow access
return NextResponse.next();
}
export const config = { export const config = {
matcher: [ matcher: [