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,35 +1,9 @@
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 token = req.nextauth.token;
const path = req.nextUrl.pathname; const path = req.nextUrl.pathname;
// Protected dashboard routes - redirect to /signup if not authenticated
const protectedRoutes = [
'/dashboard',
'/create',
'/bulk-creation',
'/analytics',
'/pricing',
'/settings',
];
// Check if current path matches any protected route
const isProtectedRoute = protectedRoutes.some(route => path.startsWith(route));
// If protected route and no token, redirect to signup
if (isProtectedRoute && !token) {
const signupUrl = new URL('/signup', req.url);
return NextResponse.redirect(signupUrl);
}
return NextResponse.next();
},
{
callbacks: {
authorized: ({ req, token }) => {
// Public routes that don't require authentication // Public routes that don't require authentication
const publicPaths = [ const publicPaths = [
'/', '/',
@ -38,27 +12,45 @@ export default withAuth(
'/blog', '/blog',
'/login', '/login',
'/signup', '/signup',
'/api/auth', '/privacy',
'/newsletter',
]; ];
const path = req.nextUrl.pathname; // Check if path is public
const isPublicPath = publicPaths.some(p => path === p || path.startsWith(p + '/'));
// Allow API routes
if (path.startsWith('/api/')) {
return NextResponse.next();
}
// 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 // Allow public paths
if (publicPaths.some(p => path.startsWith(p))) { if (isPublicPath) {
return true; return NextResponse.next();
} }
// Allow redirect routes // For protected routes, check for userId cookie
if (path.startsWith('/r/')) { const userId = req.cookies.get('userId')?.value;
return true;
if (!userId) {
// Not authenticated - redirect to signup
const signupUrl = new URL('/signup', req.url);
return NextResponse.redirect(signupUrl);
} }
// Require authentication for all other routes // Authenticated - allow access
return !!token; return NextResponse.next();
},
},
} }
);
export const config = { export const config = {
matcher: [ matcher: [