102 lines
2.7 KiB
TypeScript
102 lines
2.7 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { verifyAccessToken } from './jwt'
|
|
|
|
export interface AuthenticatedRequest extends NextRequest {
|
|
user?: {
|
|
userId: string
|
|
email: string
|
|
role: string
|
|
}
|
|
}
|
|
|
|
export const withAuth = (handler: (req: AuthenticatedRequest) => Promise<NextResponse>) => {
|
|
return async (req: AuthenticatedRequest): Promise<NextResponse> => {
|
|
try {
|
|
// Get token from Authorization header or cookie
|
|
const authHeader = req.headers.get('authorization')
|
|
const token = authHeader?.startsWith('Bearer ')
|
|
? authHeader.slice(7)
|
|
: req.cookies.get('accessToken')?.value
|
|
|
|
if (!token) {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: { message: 'No authentication token provided', code: 'NO_TOKEN' },
|
|
},
|
|
{ status: 401 }
|
|
)
|
|
}
|
|
|
|
const payload = verifyAccessToken(token)
|
|
if (!payload) {
|
|
return NextResponse.json(
|
|
{ success: false, error: { message: 'Invalid or expired token', code: 'INVALID_TOKEN' } },
|
|
{ status: 401 }
|
|
)
|
|
}
|
|
|
|
// Add user info to request
|
|
req.user = {
|
|
userId: payload.userId,
|
|
email: payload.email,
|
|
role: payload.role,
|
|
}
|
|
|
|
return handler(req)
|
|
} catch (error) {
|
|
console.error('Auth middleware error:', error)
|
|
return NextResponse.json(
|
|
{ success: false, error: { message: 'Authentication error', code: 'AUTH_ERROR' } },
|
|
{ status: 401 }
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
export const withAdminAuth = (handler: (req: AuthenticatedRequest) => Promise<NextResponse>) => {
|
|
return withAuth(async (req: AuthenticatedRequest): Promise<NextResponse> => {
|
|
if (req.user?.role !== 'admin') {
|
|
return NextResponse.json(
|
|
{
|
|
success: false,
|
|
error: { message: 'Admin access required', code: 'INSUFFICIENT_PERMISSIONS' },
|
|
},
|
|
{ status: 403 }
|
|
)
|
|
}
|
|
return handler(req)
|
|
})
|
|
}
|
|
|
|
// Helper function to get authenticated user from request
|
|
export const authMiddleware = async (
|
|
request: NextRequest
|
|
): Promise<{ id: string; email: string; role: string } | null> => {
|
|
try {
|
|
// Get token from Authorization header or cookie
|
|
const authHeader = request.headers.get('authorization')
|
|
const token = authHeader?.startsWith('Bearer ')
|
|
? authHeader.slice(7)
|
|
: request.cookies.get('accessToken')?.value
|
|
|
|
if (!token) {
|
|
return null
|
|
}
|
|
|
|
const payload = verifyAccessToken(token)
|
|
if (!payload) {
|
|
return null
|
|
}
|
|
|
|
return {
|
|
id: payload.userId,
|
|
email: payload.email,
|
|
role: payload.role,
|
|
}
|
|
} catch (error) {
|
|
console.error('Auth middleware error:', error)
|
|
return null
|
|
}
|
|
}
|